skip to Main Content

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


  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.

    Login or Signup to reply.
  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);
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search