问题
I'm using following peace of code to output an array:
echo "======output without array_unique=====";
var_dump($selected);
echo "=====output with array_unique=====";
var_dump(array_unique($selected));die;
And the output is:
======output without array_unique=====
array
0 =>
array
'uri' => string 'http://localhost/conferences/tags/0caf4c990e0a385156b33fee58e7e3fb' (length=63)
'tag' => string '1' (length=1)
'weight' => float 4
'selected' => string 'select' (length=6)
1 =>
array
'uri' => string 'http://localhost/conferences/tags/0caf4c990e0a385156b33fee58e7e3fb' (length=63)
'tag' => string '1' (length=1)
'weight' => float 4
'selected' => string 'select' (length=6)
2 =>
array
'uri' => string 'http://localhost/conferences/tags/ffc709d5131f752df8aae22d7da4240f' (length=63)
'tag' => string '2' (length=1)
'weight' => float 4
'selected' => string '' (length=0)
3 =>
array
'uri' => string 'http://localhost/conferences/tags/035c60c7f090412cc905cee008fbeba8' (length=63)
'tag' => string '3' (length=1)
'weight' => float 0
'selected' => string '' (length=0)
4 =>
array
'uri' => string 'http://localhost/conferences/tags/4137dbc16ef1a2079eb6cacb62dd8521' (length=63)
'tag' => string '4' (length=1)
'weight' => float 0
'selected' => string '' (length=0)
=====output with array_unique=====
array
0 =>
array
'uri' => string 'http://localhost/conferences/tags/0caf4c990e0a385156b33fee58e7e3fb' (length=63)
'tag' => string '1' (length=1)
'weight' => float 4
'selected' => string 'select' (length=6)
Can someone explain me, why i get array with only one element from the array_unique?
回答1:
The array elements are cast to strings for comparison - here's the relevant snippet from the manual page for array_unique
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.
Once your array elements are cast to strings, they simply have the value "Array", which of course makes every element look the same, and you wind up with just the first element.
Here's one way you could remove duplicates from an array like yours
$seen=array();
foreach ($myarray as $key=>$val) {
if (isset($seen[$val['uri']])) {
unset($myarray[$key]); // remove duplicate
} else {
$seen[$val['uri']]=$key; // remember this
}
}
unset($seen); // don't need this any more
回答2:
I imagine that since $selected is a multi-dimensional array, $selected[0] is the same as $selected[1], an array.
As far as I know, array_unique tests (string) $value1 === (string) $value2, so you get 'Array' == 'Array'.
You haven't really explained what makes an element 'unique' (the URI?). To compare whole structures, you may want to try looping through $selected, serializing the values (using serialize()) and then calling array_unique on those values. Then, call unserialize to return the array to normal.
<?php
function multi_array_unique($arr) {
foreach ($arr as &$elm) {
$elm = serialize($elm);
}
$arr = array_unique($arr);
foreach ($arr as &$elm) {
$elm = unserialize($elm);
}
return $arr;
}
?>
It isn't the most efficient solution, but I would benchmark first, before I worry about that.
See: http://codepad.org/6cs5b0sm
回答3:
array_unique removes duplicates by comparing the string value of the elements. The string value of an array is always "Array", independent of the contents of the array.
This means that all the elements of your array have the string value "Array", and are therefore considered duplicates, and are removed except for the first one.
You should write your own array_unique function that works by comparing the 'uri' of the elements.
回答4:
If the array elements are already sorted, you can find the unique values with this:
$unique = array();
$n = count($array);
if ($n < 2) {
$unique = $array;
} else {
for ($i=0; $i<$n-1; ++$i) {
$unique[] = $array[$i];
if ($array[$i] === $array[$i+1]) {
++$i;
}
}
if ($i < $n && $array[$n-2] !== $array[$n-1]) {
$unique[] = $array[$n-1];
}
}
来源:https://stackoverflow.com/questions/1403729/strange-behavior-of-php-array-unique