skip to Main Content

Given the following array of multiple arrays, I would like to return all arrays where their data isn’t duplicated in other arrays.
For example $a['test'] array should only contain arrays with keys 1,2,4,5,8 because their values aren’t duplicated in other arrays.
I am looking into array_filter function at the moment, but can’t quite get it right.
Thanks

$a['test'] = [
    1 => [
        'key_1' => 1,
        'key_2' => 2
    ],
    2 => [
        'key_1' => 7,
        'key_2' => 8
    ],
    3 => [
        'key_1' => 1,
        'key_2' => 2
    ],
    4 => [
        'key_1' => 5,
        'key_2' => 6
    ],
    5 => [
        'key_1' => 3,
        'key_2' => 4
    ],
    6 => [
        'key_1' => 1,
        'key_2' => 2
    ],
    7 => [
        'key_1' => 5,
        'key_2' => 6
    ],
    8 => [
        'key_1' => 9,
        'key_2' => 10
    ]
];

And this is how I would like the array to look like after processing

$a['test'] = [
    1 => [
        'key_1' => 1,
        'key_2' => 2
    ],
    2 => [
        'key_1' => 7,
        'key_2' => 8
    ],
    4 => [
        'key_1' => 5,
        'key_2' => 6
    ],
    5 => [
        'key_1' => 3,
        'key_2' => 4
    ],
    8 => [
        'key_1' => 9,
        'key_2' => 10
    ]
];

2

Answers


  1. array_filter isn’t terribly suited for this, because that looks at one array element at a time. You’re better off loping over your input array and populating a helper array, where you use the combination of the key_1 and key_2 values as the key (encode them as JSON, to get a unique string value for each combination) – if an entry with the key combination for the current element already exists, then you don’t add it again.

    foreach($a['test'] as $item) {
        $key = json_encode($item);
        if(!isset($helper[$key])) {
            $helper[$key] = $item;
        }
    }
    $a['test'] = array_values($helper);;
    
    print_r($a['test']);
    

    Result:

    Array
    (
        [0] => Array
            (
                [key_1] => 1
                [key_2] => 2
            )
    
        [1] => Array
            (
                [key_1] => 7
                [key_2] => 8
            )
    
        [2] => Array
            (
                [key_1] => 5
                [key_2] => 6
            )
    
        [3] => Array
            (
                [key_1] => 3
                [key_2] => 4
            )
    
        [4] => Array
            (
                [key_1] => 9
                [key_2] => 10
            )
    
    )
    

    If you need to retain the original array’s indexes in the result, then stick them into the data as well, so that you can restore them from there afterwards.

    foreach($a['test'] as $akey => $item) {
        $key = json_encode($item);
        if(!isset($helper[$key])) {
            $helper[$key] = [$akey, $item];
        }
    }
    $a['test'] = array_combine(array_column($helper, 0), array_column($helper, 1));
    
    print_r($a['test']);
    

    Result:

    Array
    (
        [1] => Array
            (
                [key_1] => 1
                [key_2] => 2
            )
    
        [2] => Array
            (
                [key_1] => 7
                [key_2] => 8
            )
    
        [4] => Array
            (
                [key_1] => 5
                [key_2] => 6
            )
    
        [5] => Array
            (
                [key_1] => 3
                [key_2] => 4
            )
    
        [8] => Array
            (
                [key_1] => 9
                [key_2] => 10
            )
    
    )
    
    Login or Signup to reply.
  2. YOu could just keep track of those you’ve checked already and unset those who exist in the $seen list:

    $seen = [];
    
    foreach ($a['test'] as $k => $v) {
        $vals = array_values($v);
    
        if (count(array_intersect($vals, $seen))) {
            unset($a['test'][$k]);
        } else {
            array_push($seen, ...$vals);
        }
    }
    
    var_dump($a['test']);
    

    Try it online!

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search