Comparing and counting an array that has similar values ​​and which don't

I have a situation where I have to compare dynamic arrays and get the number of arrays with the same values ​​only for the first four keys. For example:

Array[0]
(
    [item] => 1
    [size] => 1
    [pair] => 1
    [pay] => 1
    [name] => 
    [msg] => 
    [email] => 
    [b19e19b13682bcfef93651c86f9ad9e6] => eih6j74035oj17bvnses32km23
)
Array[1]
(
    [item] => 1
    [size] => 2
    [pair] => 1
    [pay] => 1
    [name] => 
    [msg] => 
    [email] => 
    [b19e19b13682bcfef93651c86f9ad9e6] => eih6j74035oj17bvnses32km23
)
Array[2]
(
    [item] => 1
    [size] => 2
    [pair] => 2
    [pay] => 2
    [name] => 
    [msg] => 
    [email] => 
    [b19e19b13682bcfef93651c86f9ad9e6] => eih6j74035oj17bvnses32km23
)
Array[3]
(
    [item] => 1
    [size] => 1
    [pair] => 1
    [pay] => 1
    [name] => 
    [msg] => 
    [email] => 
    [b19e19b13682bcfef93651c86f9ad9e6] => eih6j74035oj17bvnses32km23
)

I have the aforementioned array of arrays, which has the 1st and last iteration, has similar values ​​(for the 1st four keys). For this, I should get something like (0,3), (1), (2). is there any solution for this?

+4
source share
3 answers

this should work fine:

put your arrays in one array, as I did in $arrays, and then:

<?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 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);
    }
}

, $result , - $ :

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

, $ , $ [0], $ [1] $ [2] ( 1), $ [3] ( 2)

N.B: , - .

0

: , ...

$o = new SOF_ArrayComapare($yourInputArray, array('item', 'size', 'pair', 'pay', 'name'));
$arraysEqual = $o->getEqualArrays();
print $o->toString();

class SOF_ArrayComapare {
    private $_keysToMatch   = array();
    private $_array         = array();

    public function __construct($array, $keysToMatch) {
        $this->_array       = $array;
        $this->_keysToMatch = $keysToMatch;
    }

    private $_equalArrays   = array();
    private $_indexToEscape = array();

    public function getEqualArrays() {
        $size = count($this->_array);
        for ($i=0 ; $i<$size ; $i++) {

            if (in_array($i, $this->_indexToEscape))    continue;
            else                                        $this->_indexToEscape[] = $i;

            $this->_equalArrays[$i][] = $i;
            for ($j=($i+1) ; $j<$size ; $j++) {
                if (in_array($j, $this->_indexToEscape)) continue;
                if ($this->areEquals($this->_array[$i], $this->_array[$j])) {
                    $this->_indexToEscape[]     = $j;
                    $this->_equalArrays[$i][]   = $j;
                }
            }   
        }
        return $this->_equalArrays;
    }

    private function areEquals($a1, $a2) {
        foreach($this->_keysToMatch as $key) {
            if(
                !isset($a1[$key]) || 
                !isset($a2[$key]) ||
                $a1[$key] !== $a2[$key]
            ) {
                return FALSE;
            }
        }
        return TRUE;
    }

    public function toString($htmlFormat = TRUE) {
        $newLine = ($htmlFormat === TRUE) ? '<br />' : "\n";
        $report = "These arrays are equals: " . $newLine;
        foreach($this->_equalArrays as $array) {
            $report .= '(' . implode(',', $array) . ')' . $newLine;
        }
        return $report;
    }
}
0

, :

function getDuplicatesArray()
{
    $foundIndexes = array();
    $arraysCount = count(Array);
    $resultArray = array();
    // $i is current index
    // $j is compared index
    for ($i = 0; i < $arraysCount; i++)
    {
        if (in_array($i, $foundIndexes))
            continue;

        $currentResultArray = array($i);

        for ($j = $i+1; $j<$arraysCount; $j++)
        {
            if (in_array($j, $foundIndexes))
                continue;
            if(areFirstValsSame($i,$j))
            {   
                $currentResultArray[] = $j;
                if (count($currentResultArray) == 2) // first j for this i
                    foundIndexes[] = $i;
                foundIndexes[] = $j;
            }       
        }
        $resultArray[] = $currentResultArray;
    }//.. for i
}//.. getDuplicatesArray

function areFirstValsSame($index1, $index2){
    $toCompare = 4;
    for ($i=0; i<$toCompare; i++)
        if (Array($index1, i) != Array($index2, i)
            return false;
    return true; 
}

.

, "".

, .

, , .

( ) .

, : (0,1,2,3), , : (0,2), (1,3) ..

. , , .

, , .

0

Source: https://habr.com/ru/post/1622720/


All Articles