$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:
- Laravel - fetch unique rows from table having highest value in x column
- Remove duplicate objects from array based on one value, keep lowest of other value in PHP?
- Filter rows with unique column value and prioritize rows with a particular value in another column
- How to get max amount of value in same key in array
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);
Demo Link (With your Data): https://3v4l.org/f4kRM
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');