2
\$\begingroup\$

The below script will compare a set of arrays according to similarities between their key's values. For example, if the first 4 keys values of an array are equal to another array's first 4 keys values, they are equal and consists a cluster. Here is my code:

<?php
$arrays = [
array('a'=>1, 'b'=>2, 'c'=>3, 'd'=>4),
array('a'=>1, 'b'=>2, 'c'=>3, 'd'=>4),
array('a'=>1, 'b'=>2, 'c'=>3, 'd'=>4),
array('a'=>1, 'b'=>2, 'c'=>4, 'd'=>3),
];

$result = [];

//get the keys of a sub-array that is inside $arrays, to be used later
$keys = array_keys($arrays[0]);

for($i=0; $i < sizeof($arrays); $i++){

    $sa = array(); // to store similar arrays indexes

    for($k=$i+1; $k < sizeof($arrays); $k++){

        $similar = false;

        //compare the values of keys in the two arrays. Just compare the first 4 keys (as the user's desire)
        for($j=0; $j < 4; $j++){

            //check if the values are similar, if they are, assign $similar to true, and assign $j=3 to end the loop, (a bit of laziness here)
            ($similar = $arrays[$i][$keys[$j]] == $arrays[$k][$keys[$j]] ? true : false) ? null : ($j=3); 
        }

        // check if the key (which represents an index in $arrays) is in $sa or not, if not, push it.
        $similar ? (in_array($i, $sa) ? null : array_push($sa, $i) && in_array($k, $sa) ? null : array_push($sa, $k)) : null;
        //if $similar is true, make $i jumps to the $k index (saving time)
        $similar ? $i=$k : null;
    }

    //if $sa not empty, push it to $result
    empty($sa) ? null : ($result[] = $sa);
}

/* 
// at this stage, $result includes all the similar arrays
// so we need another loop to push the unique arrays to $result
// just check if an index of $arrays is in an sub-array of $result, if not, push it as an array of one record 
*/

for($j=0; $j < sizeof($arrays); $j++){
    $f = false;
    for($i=0; $i < sizeof($result); $i++){
        in_array($j, $result[$i]) ? $f = true : null;
    }
    if(!$f){
        $sa = array();
        array_push($sa, $j);
        array_push($result, $sa);
    }
}

If the result was as follows:

array(2) { 
    [0]=> array(3) { 
            [0]=> int(0) 
            [1]=> int(1) 
            [2]=> int(2) 
    },
    [1]=> array(1) { 
            [0]=> int(3) 
    } 
}

this means that $arrays has two clusters of sub-arrays, where $arrays[0], $arrays[1], and $arrays[2] are similar (cluster 1), then $arrays[3] is unique (cluster 2).

Does this code have vulnerabilities? Could it be optimized?

\$\endgroup\$
  • \$\begingroup\$ Are a number of existing array walking and sort routines that may help, such as usort \$\endgroup\$ – kph0x1 Jan 6 '16 at 14:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.