2009-09-10 3 views
3

Я использую следующий мир кода для вывода массива:странное поведение 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?

+0

Из инструкции: «Примечание: Обратите внимание, что array_unique() не предназначен для работа над многомерными массивами ». – nickf

ответ

11

Элементы массива отлиты в строки для сравнения - вот соответствующий фрагмент из manual page for array_unique

Примечание: Два элемента считаются равны тогда и только тогда, когда (строка) $ elem1 === (строка) $ elem2. В словах: когда строковое представление одно и то же. Первый элемент будет использоваться.

После того, как элементы массива передаются в строки, они просто имеют значение «Массив», что, конечно же, делает каждый элемент одинаковым, и вы завершаетесь только первым элементом.

Вот один из способов вы можете удалить дубликаты из массива, как ваша

$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 
+0

хороший выбор там. Просто для того, чтобы уточнить: любой массив, переданный в строку, представляет собой «массив», поэтому он сравнивает «массив» == «array» ' – nickf

+0

. По крайней мере, в php 5.2.6 это Array, попробуйте массив echo (string) "Foo"); –

+0

@Paul Dixon: отлично!большое спасибо за ответ и за пример! – cupakob

2

array_unique удаляет дубликаты, сравнивая строковое значение элементов. Строковое значение массива всегда «Array», независимо от содержимого массива.

Это означает, что все элементы вашего массива имеют строковое значение «Array» и поэтому считаются дублирующими и удаляются, за исключением первого.

Вы должны написать свою собственную функцию array_unique, которая работает, сравнивая «uri» элементов.

3

Я предполагаю, что поскольку $ selected является многомерным массивом, $ selected [0] совпадает с $ selected [1], массивом.

Насколько я знаю, array_unique tests (string) $ value1 === (string) $ 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; 
} 

?> 

Это не самое эффективное решение, но сначала я бы поставил перед собой задачу, прежде чем беспокоюсь об этом.

См: http://codepad.org/6cs5b0sm

0

Если элементы массива уже отсортирован, вы можете найти уникальные значения с этим:

$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]; 
    } 
} 
Смежные вопросы