comportamento estranho de array_unique php
Pergunta
Eu estou usando seguinte paz de código para a saída de um array:
echo "======output without array_unique=====";
var_dump($selected);
echo "=====output with array_unique=====";
var_dump(array_unique($selected));die;
E a saída é:
======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)
Alguém pode me explicar, porque eu recebo matriz com apenas um elemento do array_unique?
Solução
Os elementos da matriz são convertidos em seqüências para comparação - aqui está o trecho relevante do página do manual para array_unique
Nota: Dois elementos são considerados iguais se, e somente se, (string) $ elem1 === (string) $ elem2. Em palavras: quando a representação da cadeia é o mesmo. será utilizado o primeiro elemento.
Uma vez que os elementos da matriz são convertidos em cordas, eles simplesmente não têm o valor "matriz", o que naturalmente faz com que cada elemento de olhar o mesmo, e você acaba com apenas o primeiro elemento.
Aqui está uma maneira você pode remover duplicatas de uma matriz como a sua
$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
Outras dicas
Eu imagino que, desde $ selecionada é um array multi-dimensional, $ selecionado [0] é o mesmo que $ selecionada [1], uma matriz.
Tanto quanto eu sei, testes array_unique (string) $ value1 === (string) $ valor2, de modo a obter 'matriz' == 'matriz'.
Você realmente não explicou o que faz com que um elemento 'original' (o URI?). Para comparar as estruturas inteiras, você pode querer tentar loop através $ selecionado, serialização os valores (usando serialize ()) e array_unique seguida, chamar nesses valores. Em seguida, chame unserialize retornar a matriz ao 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;
}
?>
Não é a solução mais eficiente, mas eu faria referência em primeiro lugar, antes de me preocupar com isso.
array_unique remove duplicatas, comparando o valor da cadeia dos elementos. O valor da cadeia de uma matriz é sempre "matriz", independente do conteúdo da matriz.
Isto significa que todos os elementos de sua matriz têm o valor da cadeia "matriz" e, portanto, são considerados duplicados, e são removidos, exceto para o primeiro.
Você deve escrever sua própria função array_unique que funciona comparando o 'uri' dos elementos.
Se os elementos da matriz já estão classificadas, você pode encontrar os valores exclusivos com este:
$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];
}
}