2009-09-10 43 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 2009-09-10 07:05:03

回答

11

的數組元素轉換爲字符串比較 - 這裏是從manual page for 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 
+0

不錯的拿起那裏。只需詳細說明:任何數組轉換爲字符串都是'「array」',所以它比較''array「==」array「' – nickf 2009-09-10 07:03:37

+0

在php 5.2.6中至少它是Array,嘗試echo(string)array 「foo」 的); – 2009-09-10 07:08:41

+0

@ Paul Dixon:太棒了!非常感謝你的答案和例子! – cupakob 2009-09-10 07:11:39

2

array_unique通過對比元素的字符串值刪除重複,你可以從陣列中刪除重複。數組的字符串值始終爲「Array」,與數組內容無關。

這意味着數組中的所有元素都具有字符串值「Array」,因此它們被認爲是重複的,並且除第一個元素之外都將被刪除。

您應該編寫自己的array_unique函數,該函數通過比較元素的「uri」來工作。

3

我想象一下,因爲$ selected是一個多維數組,所以$ selected [0]與$ selected [1]是一個數組相同。

據我所知,array_unique測試(字符串)$ 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]; 
    } 
}