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.

2 Answers 2

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);
Sign up to request clarification or add additional context in comments.

Comments

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.

3 Comments

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.
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.
PHP 7.3 (Which is the latest on my server).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.