Home > OS >  PHP: Remove duplicate elements and get the latest data in the array
PHP: Remove duplicate elements and get the latest data in the array

Time:03-29

$arr = [
        [
            "id" => '6230061c0e88d709ca0d7bbc',
            'name' => 'Mobile SamSung',
            'slug' => 'mobile-samsung',
            'createdAt' => '1648006346'

        ],
        [
            "id" => '5d1eff529a426778d4b92383',
            'name' => 'Mobile Iphone',
            'slug' => 'mobile-iphone',
            'createdAt' => '1647314181'
        ],
        [
            "id" => '5d1eff6b9a426778d4b92dc4',
            'name' => 'Mobile SamSung',
            'slug' => 'mobile-samsung',
            'createdAt' => '1647314460'

        ],
        [
            "id" => '5f894011266aea580b028cb0',
            'name' => 'Mobile LG',
            'slug' => 'mobile-lg',
            'createdAt' => '1647314456'

        ]
    ];

I have an array, and in this array there are many duplicate subarrays, now I want to remove the duplicate arrays inside, keeping only the data with the latest createdAt. Please give me your opinion. Thanks

I would like to get an array like this:

$arr = [
            [
                "id" => '6230061c0e88d709ca0d7bbc',
                'name' => 'Mobile SamSung',
                'slug' => 'mobile-samsung',
                'createdAt' => '1648006346'

            ],
            [
                "id" => '5d1eff529a426778d4b92383',
                'name' => 'Mobile Iphone',
                'slug' => 'mobile-iphone',
                'createdAt' => '1647314181'
            ],
            [
                "id" => '5f894011266aea580b028cb0',
                'name' => 'Mobile LG',
                'slug' => 'mobile-lg',
                'createdAt' => '1647314456'

            ]
        ];

CodePudding user response:

You should not make more than one pass over your data. Just use the name values as temporary keys, then only retain a duplicate row's data if its createAt value is greater than what is stored. Re-index the array when you are finished looping.

Code: (Demo)

$result = [];
foreach ($arr as $row) {
    if (!isset($result[$row['name']]) || (int)$row['createdAt'] > (int)$result[$row['name']]['createdAt']) {
        $result[$row['name']] = $row;
    }
}
var_export(array_values($result));

Output:

array (
  0 => 
  array (
    'id' => '6230061c0e88d709ca0d7bbc',
    'name' => 'Mobile SamSung',
    'slug' => 'mobile-samsung',
    'createdAt' => '1648006346',
  ),
  1 => 
  array (
    'id' => '5d1eff529a426778d4b92383',
    'name' => 'Mobile Iphone',
    'slug' => 'mobile-iphone',
    'createdAt' => '1647314181',
  ),
  2 => 
  array (
    'id' => '5f894011266aea580b028cb0',
    'name' => 'Mobile LG',
    'slug' => 'mobile-lg',
    'createdAt' => '1647314456',
  ),
)

Potentially helpful:

CodePudding user response:

First sort on created at, then remove duplicates.

<?php
$arr = [
        [
            "id" => '6230061c0e88d709ca0d7bbc',
            'name' => 'Mobile SamSung',
            'slug' => 'mobile-samsung',
            'createdAt' => '1648006346'

        ],
        [
            "id" => '5d1eff529a426778d4b92383',
            'name' => 'Mobile Iphone',
            'slug' => 'mobile-iphone',
            'createdAt' => '1647314181'
        ],
        [
            "id" => '5d1eff6b9a426778d4b92dc4',
            'name' => 'Mobile SamSung',
            'slug' => 'mobile-samsung',
            'createdAt' => '1647314460'

        ],
        [
            "id" => '5f894011266aea580b028cb0',
            'name' => 'Mobile LG',
            'slug' => 'mobile-lg',
            'createdAt' => '1647314456'

        ]
    ];
    
function sort_objects_by_created($a, $b) {
    if($a['createdAt'] == $b['createdAt']){ return 0 ; }
    return ($a['createdAt'] > $b['createdAt']) ? -1 : 1;
}

// Let's sort
usort($arr, 'sort_objects_by_created');

$slugs = [];
$result = [];

// Loop object
foreach($arr as $phone) {
    // If slug is not found, add to result
    if (!in_array($phone['slug'], $slugs)){
        $slugs[] = $phone['slug'];
        $result[] = $phone;
    }    
}    

var_dump($result,$slugs);

CodePudding user response:

Explanation:

In this solution, I have gotten the data with a unique slug key with the latest createdAt key. we can have any unique key that matches into the multidimensional array and get the result whatever we want.

Code:

$newArray = [];
foreach ($array as $key => $value) {
    $findIndex = array_search($value['slug'], array_column($newArray, 'slug'));
    if ($findIndex === false) {
        $newArray[] = $value;
    } elseif ($findIndex !== false && $newArray[$findIndex]['createdAt'] <= $value['createdAt']) {
        $newArray[$findIndex] = $value;
    }
}
print_r($newArray);
  1. Demo Link (With your Data): https://3v4l.org/f4kRM

  2. Demo Link (Customized Data with my way): https://3v4l.org/sj4MW

CodePudding user response:

Might be worth a note, that you might be able to improve this upstream when creating your array. (always look upstream!)

If you can give you base array a key of created At you can use Array sorting, which which will this step more effecient....

E.g.

$arr = [];
$arr[2022-01-01] = Array('id' => 123, 'name' = 'abc');
$arr[2022-04-01] = Array('id' => 123, 'name' = 'abc');
$arr[2022-08-01] = Array('id' => 123, 'name' = 'abc');
  • Related