Filter/Remove rows where column value is found more than once in a multidimensional array
For a clearer "minimal, complete, verifiable example", I'll use the following input array in my demos:
$array = [
['user_id' => 82, 'ac_type' => 1],
['user_id' => 80, 'ac_type' => 5],
['user_id' => 76, 'ac_type' => 1],
['user_id' => 82, 'ac_type' => 2],
['user_id' => 80, 'ac_type' => 5]
];
// elements [0] and [3] have the same user_id, but different ac_type
// elements [1] and [4] have identical row data
Unconditionally push rows into a result array and assign associative first-level keys, then re-index with
array_values()
. This approach overwrites earlier duplicate rows with later occurring ones.array_column demo:
var_export(array_values(array_column($array, null, 'user_id')));
foreach demo:
$result = [];
foreach ($array as $row) {
$result[$row['user_id']] = $row;
}
var_export(array_values($result));Output:
[
['user_id' => 82, 'ac_type' => 2], // was input row [3]
['user_id' => 80, 'ac_type' => 5], // was input row [4]
['user_id' => 76, 'ac_type' => 1] // was input row [2]
]Use a condition or the null coalescing assignment operator to preserve the first occurring row while removing duplicates.
foreach null coalescing assignment demo:
foreach ($array as $a) {
$result[$a['user_id']] ??= $a; // only store if first occurrence of user_id
}
var_export(array_values($result)); // re-index and printforeach isset demo:
foreach ($array as $a) {
if (!isset($result[$a['user_id']])) {
$result[$a['user_id']] = $a; // only store if first occurrence of user_id
}
}
var_export(array_values($result)); // re-index and printOutput:
[
['user_id' => 82, 'ac_type' => 1], // was input row [0]
['user_id' => 80, 'ac_type' => 5], // was input row [1]
['user_id' => 76, 'ac_type' => 1] // was input row [2]
]It is also possible to unconditionally push data AND avoid a condition, but the row order may differ between the input and output (if it matters to you).
array_reverse, array_column demo:
var_export(array_values(array_column(array_reverse($array), null, 'user_id')));
array_reduce demo:
var_export(
array_values(
array_reduce(
$array,
fn($res, $row) => array_replace([$row['user_id'] => $row], $res),
[]
)
)
);foreach array_reverse demo:
$result = [];
foreach (array_reverse($array) as $row) {
$result[$row['user_id']] = $row;
}
var_export(array_values($result));Output:
[
['user_id' => 80, 'ac_type' => 5], // was input row [1]
['user_id' => 82, 'ac_type' => 1], // was input row [0]
['user_id' => 76, 'ac_type' => 1] // was input row [2]
]
A warning about a fringe case not expressed in this example: if you are using row values as identifiers that may be corrupted upon being used as keys, the above techniques will give unreliable results. For instance, PHP does not allow float values as keys (they will cause an error or be truncated, depending on your PHP version). Only in these fringe cases might you consider using inefficient, iterated calls of in_array()
to evaluate uniqueness.
Using array_unique(..., SORT_REGULAR)
is only suitable when determining uniqueness by ENTIRE rows of data.
array_unique demo:
var_export(array_unique($array, SORT_REGULAR));
Output:
[
['user_id' => 82, 'ac_type' => 1], // was input row [0]
['user_id' => 80, 'ac_type' => 5], // was input row [1]
['user_id' => 76, 'ac_type' => 1] // was input row [2]
['user_id' => 82, 'ac_type' => 2], // was input row [3]
]
How to remove duplicates value of same key of multidimensional array in PHP
If you need only latest entry for each unique status, you can simply use status
's value as a key in another associative array and keep overriding it at every iteration in the loop. In the end, you will only be left with unique results with latest entries.
Say, you have this array in a variable called $data
, then you could loop like below:
<?php
$set = [];
foreach($data as $o){
$set[ $o->status ] = $o;
}
$set = array_values($set);// if you don't like status keys
print_r($set);
Remove all duplicate data from a multi-dimensional array
So the issue here is that the array_unique
solutions expect the entire value to be equivalent - they don't just compare based on your ID field.
Instead, you probably want to loop through the array and keep track of which IDs you've seen, and only take those elements for which you haven't seen the ID before.
function filter_duplicate_id_cards($data) {
$seen = array(); // To keep track of the IDs we've seen
$filtered = array(); // Will hold the result
foreach($data as $item) {
if(array_key_exists($item['id_card'], $seen)) {
// We already encountered this id card before.
continue;
}
// Never-before seen id card, append it to the result and set the key in $seen
$filtered[] = $item;
$seen[$item['id_card']] = TRUE;
}
return $filtered;
}
Note that this uses the map form of a PHP array, rather than just appending seen IDs to the list form and using something like in_array
to check if we've seen the key. That's important for performance reasons, especially if we're going to be working on large datasets - in_array
is O(n) with the # of items in the array whereas array_key_exists
is O(1).
A more generic version of this function would look like this:
function filter_duplicate_field($data, $field) {
$seen = array(); // To keep track of the keys we've seen
$filtered = array(); // Will hold the result
foreach($data as $item) {
if(array_key_exists($item[$field], $seen)) {
// We already encountered this key before.
continue;
}
// Never-before seen key, append it to the result and set the key in $seen
$filtered[] = $item;
$seen[$item[$field]] = TRUE;
}
return $filtered;
}
You could then call it like $result = filter_duplicate_field($data, 'id_card');
.
Filter array of associative rows to retain only rows with unique value in specified column
Simple solution using regular foreach
loop:
$rows = [
['id' => 1, 'code' => '342'],
['id' => 2, 'code' => '765'],
['id' => 3, 'code' => '134'],
['id' => 1, 'code' => '342']
];
$ids = [];
foreach ($rows as $k => $item) {
if (in_array($item['id'], $ids)){
unset($rows[$k]);
} else {
$ids[] = $item['id'];
}
}
print_r($rows);
PHP - Elegant way of removing values from Associative Arrays based on a key value duplication
return array_intersect_key($results, array_unique(array_column($results, 'nid')));
How to remove duplicate entries from multidimensional array?
Serialization is used to compare if the entire arrays are indentical, not just one key.
You can extract the array and index (which must be unique) by linked_article_id
:
$input = array_column($input, null, 'linked_article_id');
If you really need to re-index after (optional):
$input = array_values(array_column($input, null, 'linked_article_id'));
I don't see how anyone could be running PHP < 5.5.0 now, but just in case:
foreach($input as $v) {
$result[$v['linked_article_id']] = $v;
}
Then if needed:
$result = array_values($result);
PHP - array_map 2 columns and remove duplicate rows by key
If you want the first occurrence use @TheFirstBird answer. If you want the last occurrence you can do it simpler buy using array_column
and array_values
as:
$newArr = array_values(array_column($purchases, null, "product_id"));
Notice the second argument of array_column
is null meaning take the entire element.
Live example: 3v4l
References: array-column, array-values
Removing duplicate array values by e-mail
A simple way if you are using a loop to add the details in ( which is what I am assuming your current code is doing) is to index the $guestOutput
by the e-mail address. So as you add in new details, you will just overwrite the previous details...
$guestOutput[$guest->guestEmail] = [
'firstName' => $guest->guestFirstName,
'lastName' => $guest->guestLastName,
'email' => $guest->guestEmail,
];
If you don't need the index at the end of the loop, you can use:
$guestOutput = array_values($guestOutput);
Related Topics
Is There a Use-Case For Singletons With Database Access in PHP
Fatal Error: Allowed Memory Size of 134217728 Bytes Exhausted (Codeigniter + Xml-Rpc)
PHP Does Not Display Error Messages
Matching Unicode Letter Characters in Pcre/PHP
PHP Fatal Error: Using $This When Not in Object Context
How to Find All Youtube Video Ids in a String Using a Regex
Many-To-Many Relationships Examples
Simplest Two-Way Encryption Using PHP
Getting the Location from an Ip Address
How to Create Multiple Where Clause Query Using Laravel Eloquent
How to Prevent Form Resubmission When Page Is Refreshed (F5/Ctrl+R)
Startswith() and Endswith() Functions in PHP
MySQL Query to Get Column Names
Simplexml: Selecting Elements Which Have a Certain Attribute Value
Multiple Returns from a Function
What in Layman'S Terms Is a Recursive Function Using PHP
Convert a Series of Parent-Child Relationships into a Hierarchical Tree