странное поведение php array_unique
Вопрос
Я использую следующий код для вывода массива:
echo "======output without array_unique=====";
var_dump($selected);
echo "=====output with array_unique=====";
var_dump(array_unique($selected));die;
И вывод:
======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)
Может кто-нибудь объяснить мне, почему я получаю массив только с одним элементом из array_unique?
Решение
Элементы массива приводятся в строки для сравнения - вот соответствующий фрагмент со страницы руководства для array_unique р>
Примечание: рассматриваются два элемента равен тогда и только тогда, когда (строка) $ elem1 === (строка) $ elem2. На словах: когда строковое представление одинаково. Первый элемент будет использован.
Как только ваши элементы массива приводятся к строкам, они просто имеют значение "Array", что, конечно, заставляет каждый элемент выглядеть одинаково, и вы получаете только первый элемент.
Вот один из способов, как вы можете удалить дубликаты из массива, подобного вашему
$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
Другие советы
Я предполагаю, что, поскольку $ selected является многомерным массивом, $ selected [0] совпадает с $ selected [1], массивом.
Насколько я знаю, array_unique тестирует (строка) $ value1 === (строка) $ value2, поэтому вы получаете 'Array' == 'Array'.
Вы действительно не объяснили, что делает элемент «уникальным» (URI?). Чтобы сравнить целые структуры, вы можете попробовать пройтись по $ selected, сериализовать значения (используя serialize ()) и затем вызвать array_unique для этих значений. Затем вызовите unserialize, чтобы вернуть массив в нормальное состояние.
<?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;
}
?>
Это не самое эффективное решение, но я бы сначала проверил, прежде чем беспокоиться об этом.
array_unique удаляет дубликаты, сравнивая строковое значение элементов. Строковое значение массива всегда равно «Массив», независимо от содержимого массива.
Это означает, что все элементы вашего массива имеют строковое значение " Array " и поэтому считаются дубликатами и удаляются, кроме первого.
Вы должны написать свою собственную функцию array_unique, которая работает путем сравнения 'uri' элементов.
Если элементы массива уже отсортированы, вы можете найти уникальные значения с помощью этого:
$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];
}
}