How do I use array_unique on an array of arrays?
It's because array_unique
compares items using a string comparison. From the docs:
Note: Two elements are considered
equal if and only if (string) $elem1
=== (string) $elem2. In words: when the string representation is the same.
The first element will be used.
The string representation of an array is simply the word Array
, no matter what its contents are.
You can do what you want to do by using the following:
$arr = array(
array('user_id' => 33, 'frame_id' => 3),
array('user_id' => 33, 'frame_id' => 3),
array('user_id' => 33, 'frame_id' => 8)
);
$arr = array_intersect_key($arr, array_unique(array_map('serialize', $arr)));
//result:
array
0 =>
array
'user_id' => int 33
'user' => int 3
2 =>
array
'user_id' => int 33
'user' => int 8
Here's how it works:
Each array item is serialized. This
will be unique based on the array's
contents.The results of this are run through
array_unique
,
so only arrays with unique
signatures are left.array_intersect_key
will take
the keys of the unique items from
the map/unique function (since the source array's keys are preserved) and pull
them out of your original source
array.
array_unique for arrays inside array
You should modify your call for array_unique
to have it include the SORT_REGULAR
flag.
$arr2 = array_unique($arr, SORT_REGULAR);
How to remove duplicate values from a multi-dimensional array in PHP
Here is another way. No intermediate variables are saved.
We used this to de-duplicate results from a variety of overlapping queries.
$input = array_map("unserialize", array_unique(array_map("serialize", $input)));
How can you get unique values from multiple arrays using array_unique?
The answer to the first part of your question is NO.
The array_unique function definition in the PHP manual states that array_unique
takes exactly two arguments, one array, and an optional integer that determines the sorting behavior of the function.
array array_unique ( array $array [, int $sort_flags = SORT_STRING ] )
Rather than take the manual's word for it, here are some test arrays.
$one_array = ['thing', 'another_thing', 'same_thing', 'same_thing'];
$two_arrays = ['A', 'B', 'C', 'thing', 'same_thing'];
$or_more_arrays = ['same_thing', 1, 2, 3];
A couple of test show that the function does work as advertised:
$try_it = array_unique($one_array);
returns ['thing', 'another_thing', 'same_thing'];
$try_it = array_unique($one_array, $two_arrays);
gives you a warning
Warning: array_unique() expects parameter 2 to be integer, array given
and returns null
.
$try_it = array_unique($one_array, $two_arrays, $or_more_arrays);
also gives you a warning
Warning: array_unique() expects at most 2 parameters, 3 given
and returns null
.
The answer to the second part of your question is YES.
To get unique values using array_unique, you do have to have one array of values. You can do this, as u_mulder commented, by using array_merge
to combine the various input arrays into one before using array_unique
.
$unique = array_unique(array_merge($one_array, $two_arrays, $or_more_arrays));
returns
['thing', 'another_thing', 'same_thing', 'A', 'B', 'C', 1, 2, 3];
If instead of several individual array variables, you have an array of arrays like this:
$multi_array_example = [
[1, 2, 3],
[2, 3, 4],
[3, 4, 5],
[4, 5, 6]
];
Then you can unpack the outer array into array merge to flatten it before using array_unique
.
$unique = array_unique(array_merge(...$multi_array_example));
Or in older PHP versions (<5.6) before argument unpacking, you can use array_reduce
with array_merge
.
$unique = array_unique(array_reduce($multi_array_example, 'array_merge', []));
returns [1, 2, 3, 4, 5, 6]
array unique for multi dimensional array in php
Why are you making it so hard,
$in = array (
1 =>
array (
'country' => 'US',
'state' => 'Albama',
'city' => 'Brest',
'postcode' => '225001-225003',
'shipping_info' => 'DeliveryAvailable',
'is_zip_range' => 1,
'zip_from' => 225001,
'zip_to' => 225003
),
2 =>
array (
'country' => 'BY',
'state' => 'Brest',
'city' => 'Brest',
'postcode' => '225001-225003',
'shipping_info' => 'DeliveryAvailable',
'is_zip_range' => 1,
'zip_from' => 225001,
'zip_to' => 225003
)
);
$out = [];
foreach($in as $i) if(!isset($out[$i['postcode']])) $out[$i['postcode']] = $i;
Sandbox
You can do the same thing with in_array, but the isset is faster.
In fact you dont even need to do the isset
foreach($in as $i) $out[$i['postcode']] = $i;
Array keys are always unique, but this will retain the last duplicate where as the previous code keeps the first one.
And if the keys bug you latter just do $out = array_values($out)
to reset them.
array_unique for objects?
Well, array_unique()
compares the string value of the elements:
Note: Two elements are considered equal if and only if
(string) $elem1 === (string) $elem2
i.e. when the string representation is the same, the first element will be used.
So make sure to implement the __toString()
method in your class and that it outputs the same value for equal roles, e.g.
class Role {
private $name;
//.....
public function __toString() {
return $this->name;
}
}
This would consider two roles as equal if they have the same name.
array_unique inconsistent for simple arrays
array_unique([1,2,3,4,4])
returns:
array(4) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
[3]=>
int(4)
}
Note that the keys are sequential
While array_unique([1,2,3,3,4]))
returns:
array(4) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
[4]=>
int(4)
}
Note the jump between the key
2
and the key4
.
Because of that - json_encode
will omit the keys
in the first array (and keep it as array
object), while in the second array - the json_encode
will look at your array
as object
and will keep the keys.
You can use array_values
(to get the values and ignore the keys
).
How to remove duplicate values from an array in PHP
Use array_unique().
Example:
$array = array(1, 2, 2, 3);
$array = array_unique($array); // Array is now (1, 2, 3)
PHP array_unique is converted to object
The function array_unique()
filters out equal values so the reason why #3 of the index is missing is because its equal to #0.
You can re-index the array with array_values()
:
var_dump(array_values(array_unique($errors, SORT_REGULAR)));
JavaScript perceives PHP's associative array's as an object because it only understands numeric keyed arrays.
You should be using json to communicate between both languages:
echo json_encode($errors);
As this would cause in javascript the outer the value to be turned into an array and turn each item into an object.
var arr = JSON.parse(outputofjson_encode);
console.log(arr[0].id);
Related Topics
Zf2 - Get Controller Name into Layout/Views
Oauth Implementation in Netsuite Using PHP
How to Use String Concatenation to Define a Class Const in PHP
PHP Localization Best Practices? Gettext
Overwrite Line in File with PHP
PHP Method Argument Type Hinting with Question Mark (Type)
Get All Orders Ids from a Product Id in Woocommerce
Is_Null($X) VS $X === Null in PHP
Yii2 Translation Does Not Work
Good Error Handling with File_Get_Contents
PHP Datetime Round Up to Nearest 10 Minutes
Array_Map Function in PHP with Parameter
Multiple Replace (Probably Preg_Replace) of Same String with Array