Reputation: 107
I have a PHP array with indexes, its values can be duplicated. I want to remove all duplicated indexes from this array:
array(3) {
[0]=>
array(5) {
["uid"]=>
int(1)
["title"]=>
string(26) "Title A"
["tstamp"]=>
string(10) "1580296755"
}
[1]=> // <----- should be removed, because it's tstamp is lower than it's duplicate
array(5) {
["uid"]=>
int(2)
["title"]=>
string(33) "Title B" // <----- duplicate value
["tstamp"]=>
string(10) "1580296797"
}
[2]=>
array(5) {
["uid"]=>
int(3)
["title"]=>
string(33) "Title B" // <----- duplicate value
["tstamp"]=>
string(10) "1580298366"
}
}
So, Index 1 and 2 with the same title "Title B" are duplicated. Only the one with the higher tstamp should be exists, all older ones with same title should be removed from array:
array(3) {
[0]=>
array(5) {
["uid"]=>
int(1)
["title"]=>
string(26) "Title A"
["tstamp"]=>
string(10) "1580296755"
}
[1]=>
array(5) {
["uid"]=>
int(3)
["title"]=>
string(33) "Title B"
["tstamp"]=>
string(10) "1580298366"
}
}
Hope someone understand me and can help to solve my problem.
Upvotes: 0
Views: 1013
Reputation: 11943
I don't believe you're actual concern here is the array keys, as your questions posits. I believe your real concern is in preventing duplicate values. If the array were sorted by the 'tstamp
key this would be a simple column pluck operation.
So assuming ...
$arr = [
['uid' => 1, 'title' => 'Title A', 'tstamp' => 1580296755],
['uid' => 2, 'title' => 'Title B', 'tstamp' => 1580296797],
['uid' => 3, 'title' => 'Title B', 'tstamp' => 1580298366],
];
// Sorted ascendingly by 'tstamp' key
uasort($arr, function($a, $b) { return $a['tstamp'] <=> $b['tstamp']; });
// Pluck the title and overwriting is automatic
$result = array_column($arr, null, 'title');
var_dump($result);
The result would be:
array(2) { ["Title A"]=> array(3) { ["uid"]=> int(1) ["title"]=> string(7) "Title A" ["tstamp"]=> int(1580296755) } ["Title B"]=> array(3) { ["uid"]=> int(3) ["title"]=> string(7) "Title B" ["tstamp"]=> int(1580298366) } }
Upvotes: 2
Reputation: 4599
You can use in_array
function in such way:
$tmp = [];
foreach($ar as $ind=>$set){
if(!in_array($set['title'],$tmp)){
$tmp[] = $set['title'];
} else {
unset($ar[$ind]);
}
}
print_r($ar);
Output:
Array
(
[0] => Array
(
[uid] => 1
[title] => Title A
[tstamp] => 1580296755
)
[1] => Array
(
[uid] => 2
[title] => Title B
[tstamp] => 1580296755
)
[3] => Array
(
[uid] => 4
[title] => Title C
[tstamp] => 1580296755
)
)
or if you need to leave the last one appearance you can use next code:
$tmp = [];
$res = [];
foreach($ar as $ind=>$set){
$tmp[$set['title']] = $ind;
}
foreach($tmp as $title=>$ind){
$res[] = $ar[$ind];
}
print_r($res);
Output:
Array
(
[0] => Array
(
[uid] => 1
[title] => Title A
[tstamp] => 1580296755
)
[1] => Array
(
[uid] => 3
[title] => Title B
[tstamp] => 1580296755
)
[2] => Array
(
[uid] => 4
[title] => Title C
[tstamp] => 1580296755
)
)
Upvotes: 0
Reputation: 8621
Just create an empty array, loop through your old array and add them to the new array with the key as the title.
<?php
$old = [
['uid' => 1, 'title' => 'Title A', 'tstamp' => 1580296755],
['uid' => 2, 'title' => 'Title B', 'tstamp' => 1580296797],
['uid' => 3, 'title' => 'Title B', 'tstamp' => 1580298366],
];
$new = [];
foreach($old as $row) {
$title = $row['title'];
//check if title exists as key of `$new` array.
//if it does exist as a key, check if `tstamp` in the loop is higher than the existing record
if(!array_key_exists($title, $new) || ($new[$title]['tstamp'] < $row['tstamp'])) {
//update or insert record if the if-statement evaluates to true
$new[$title] = $row;
}
}
Output:
Array
(
[Title A] => Array
(
[uid] => 1
[title] => Title A
[tstamp] => 1580296755
)
[Title B] => Array
(
[uid] => 3
[title] => Title B
[tstamp] => 1580298366
)
)
This has the added benefit of being able to select titles easier, for example $new['Title A']
. If you want the key indexes to still be numerical, you can use $new = array_values($new);
to do so. If you use array_values()
, the output matches your expected output exactly.
Upvotes: 1