【问题标题】:strange behavior of php array_uniquephp array_unique 的奇怪行为
【发布时间】:2009-09-10 06:56:34
【问题描述】:

我正在使用以下代码来输出数组:

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() 不适用于多维数组。”

标签: php arrays unique behavior


【解决方案1】:

数组元素被转换为字符串以供比较 - 这是来自manual page for array_unique的相关sn-p

注意:考虑两个元素 当且仅当(字符串)$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

【讨论】:

  • 那里不错。只是为了详细说明:任何转换为​​字符串的数组都是"array",所以它比较"array" == "array"
  • 至少在 php 5.2.6 中是 Array,试试 echo (string)array("foo");
  • @Paul Dixon:太好了!非常感谢您的回答和示例!
【解决方案2】:

我想既然$selected是一个多维数组,那么$selected[0]和$selected[1]一样,是一个数组。

据我所知,array_unique 测试 (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

【讨论】:

    【解决方案3】:

    array_unique 通过比较元素的字符串值来删除重复项。数组的字符串值始终为“Array”,与数组的内容无关。

    这意味着您的数组中的所有元素都具有字符串值“Array”,因此被视为重复元素,除了第一个元素外,将被删除。

    您应该编写自己的 array_unique 函数,该函数通过比较元素的“uri”来工作。

    【讨论】:

      【解决方案4】:

      如果数组元素已经排序,你可以用这个找到唯一值:

      $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];
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-07-08
        • 2013-08-09
        • 2021-11-21
        • 2018-05-20
        • 2012-01-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多