简体   繁体   中英

find duplicates in associative array PHP, compare their values

This is my array:

[0] => Array
    (
        [0] => SupSKU
        [1] => MfrSKU
        [2] => Cost
    )

[1] => Array
    (
        [0] => A
        [1] => 11742-4
        [2] => 47.25
    )

[2] => Array
    (
        [0] => B
        [1] => 11742-4
        [2] => 283.5
    )

[3] => Array
    (
        [0] => C
        [1] => 0904101
        [2] => 995
    )

I want to find duplicates values in Mfrsku value, in this example that is 11742-4, then compare their prices, and save bigger price SupSku value. So my output will be

$final_output => Array ( 
  [0] => B
)

I tried with this but this only retun empty array

array_unique(array_diff_assoc($ar,array_unique($ar)));

This is probably not the best performance, it got more nested than I wanted.

I use array_column and array_count_values to get how many times they are in the array, then array_diff removes the unique values.
I loop the duplicates and find the maximum prices that is associated to the duplicate and save them in an associative array.

$Mfr= array_column($arr, 1);
$dupes = array_diff(array_count_values($Mfr), [1]);

foreach($dupes as $key => $val){
    $res[$key] = max(array_intersect_key(array_column($arr, 2), array_intersect($Mfr, [$key])));
}

var_dump($res);
/*
array(1) {
  ["11742-4"]=>
  string(5) "283.5"
}
*/

https://3v4l.org/8v1Q0


I now save the intersect in a temporary array that I then can search in order to find what key has the maximum value.
I then use this key to get the [0] value which is "B".

$Mfr= array_column($arr, 1);
$dupes = array_diff(array_count_values($Mfr), [1]);

foreach($dupes as $key => $val){
    $temp = array_intersect_key(array_column($arr, 2), array_intersect($Mfr, [$key]));
    $res[$key] = $arr[array_search(max($temp), $temp)][0];

}

var_dump($res);
/*
array(1) {
  ["11742-4"]=>
  string(1) "B"
}
*/

https://3v4l.org/dSpBi


I reworked the code in order to make it faster.
I used to use lots of loops in the background with array_intersect and array_column.
This code will now do more looping "front end" but instead create a multidimensional associative array that is quick to manipulate.

The code first creates a new array with [MfrSKU][SupSKU] = Cost.
Then I loop this array and if the count is one then there is no duplicates.

If there is duplicates I remove the minimum value and grab the keys and save them to the result array.

foreach(array_slice($arr,1) as $sub){
    $new[$sub[1]][$sub[0]] = $sub[2];
}

foreach($new as $key => $sub){
    if(count($sub) == 1){ 
        continue;
    }
    $res[$key] = array_keys(array_diff($sub, [min($sub)]));
}

var_dump($res);

https://3v4l.org/20C2v

According to 3v4l it's about six times faster code in php 7.3.3

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM