0

I am trying to create an array where I need to filter with a certain key (fileid) so that it returns only unique keys for parent array. Here is what I have..

Array
(
    [ABCD] => Array
        (
            [0] => Array
                (
                    [fileid] => 5454554
                    [filename] => myfile1.txt
                )

            [1] => Array
                (
                    [fileid] => 5454954
                    [filename] => myfile2.txt
                )

            [2] => Array
                (
                    [fileid] => 5454554
                    [filename] => myfile1.txt
                )

        )

    [EFGH] => Array
        (
            [0] => Array
                (
                    [fileid] => 5429654
                    [filename] => myfile2.txt
                )

            [1] => Array
                (
                    [fileid] => 5433954
                    [filename] => myfile2.txt
                )

            [2] => Array
                (
                    [fileid] => 5429654
                    [filename] => myfile1.txt
                )

        )

)

The first keys (ABCD and EFGH) are File Owner IDs. The nested arrays contains the File ID and the FIle Name. I need to filter it so that every duplicate nested array (having same fileid) is removed.

I tried this this and this and many other solutions found on the web. But no luck. I also tried

$result =  array_map("unserialize", array_unique(array_map("serialize", $file_array)));  

No Luck again. Can someone please guide me to the right direction?

Thanks in advance.

Abhik
  • 664
  • 3
  • 22
  • 40

2 Answers2

2

A simple couple of loops where you remember the fileid's that you have seen in the inner array. If you see a fileid twice, you unset that occurance of the array. Note using &$owners in the outer loop so you can actually remove an occurance from within the foreach loop

$input = [  'ABCD' => [
                    ['fileid' => 5454554, 'filename' => 'myfile1.txt'],
                    ['fileid' => 5454954, 'filename' => 'myfile2.txt'],
                    ['fileid' => 5454554, 'filename' => 'myfile1.txt']
                    ],
            'EFGH' => [
                    ['fileid' => 5429654, 'filename' => 'myfile2.txt'],
                    ['fileid' => 5433954, 'filename' => 'myfile2.txt'],
                    ['fileid' => 5429654, 'filename' => 'myfile1.txt']
            ]
];
foreach ($input as &$owners){
    $ids = [];
    foreach($owners as $i=>$file){
        if ( in_array($file['fileid'], $ids) ){
            unset($owners[$i]);
        } else {
            $ids[] = $file['fileid'];
        }
    }
}
print_r($input);

RESULT

Array
(
    [ABCD] => Array
        (
            [0] => Array
                ( [fileid] => 5454554, [filename] => myfile1.txt )

            [1] => Array
                ( [fileid] => 5454954, [filename] => myfile2.txt )
        )
    [EFGH] => Array
        (
            [0] => Array
                ( [fileid] => 5429654, [filename] => myfile2.txt )

            [1] => Array
                ( [fileid] => 5433954,  [filename] => myfile2.txt )
        )
)

OR

Build a new array containing only the non duplicated files

$input = [  'ABCD' => [
                    ['fileid' => 5454554, 'filename' => 'myfile1.txt'],
                    ['fileid' => 5454954, 'filename' => 'myfile2.txt'],
                    ['fileid' => 5454554, 'filename' => 'myfile1.txt']
                    ],
            'EFGH' => [
                    ['fileid' => 5429654, 'filename' => 'myfile2.txt'],
                    ['fileid' => 5433954, 'filename' => 'myfile2.txt'],
                    ['fileid' => 5429654, 'filename' => 'myfile1.txt']
            ]
];
$new = [];
foreach ($input as $owner => $files){
    $t = [];
    $ids = [];

    foreach($files as $i=>$file){
        if ( ! in_array($file['fileid'], $ids) ){
            $t[] = $file;
            $ids[] = $file['fileid'];
        }
    }
    $new[$owner] = $t;
}
print_r($new);
RiggsFolly
  • 93,638
  • 21
  • 103
  • 149
1

You can use a combination of array_map and array_filter like so:

array_map(
    function($arr) {
        $exists = [];
        return array_values(
            array_filter(
                $arr,
                function($arr1) use (&$exists) {
                    if (isset($exists[$arr1['fileid']])) {
                        return false;
                    }
                    $exists[$arr1['fileid']] = true;
                    return true;
                }
            )
        );
    },
    $file_array,
);

Note: I used array_values to ensure the resultant array has consecutive numerical keys. If you want to keep the original numerical keys then it can be omitted.

MC57
  • 329
  • 1
  • 5
  • Giving me an error :( PHP Parse error: syntax error, unexpected ')' in /home/aMlGCD/prog.php on line 57 (which is the closing of `array_map`. – Abhik Mar 03 '23 at 15:57
  • Which version of PHP are you using? It works fine for me. Most likely you're using an older version of PHP and you need to remove the trailing commas. – MC57 Mar 03 '23 at 16:16
  • PHP 7.3 (Which is the latest on my server). – Abhik Mar 03 '23 at 17:19