【问题标题】:php filter array values and remove duplicates from multi dimensional arrayphp过滤数组值并从多维数组中删除重复项
【发布时间】:2014-02-24 23:07:45
【问题描述】:

大家好,我试图从这个数组中找到重复的 x 值并删除它们,只留下唯一的值。例如我的数组是

Array
(
[0] => Array
    (
        [x] => 0.5
        [y] => 23
    )

[1] => Array
    (
        [x] => 23
        [y] => 21.75
    )

[2] => Array
    (
        [x] => 14.25
        [y] => 21.875
    )

[3] => Array
    (
        [x] => 19.375
        [y] => 21.75
    )

[4] => Array
    (
        [x] => 9.125
        [y] => 21.875
    )

[5] => Array
    (
        [x] => 23
        [y] => 19.625
    )

[6] => Array
    (
        [x] => 19.375
        [y] => 19.625
    ) 
)

所以我需要做的是循环遍历整个事物,然后将第一个 x 值视为 .5 然后继续,将 x 为 .5 的任何其他内容从数组中删除,以便最后我有一个看起来像这样

 Array
   (
[0] => Array
    (
        [x] => 0.5
        [y] => 23
    )

[1] => Array
    (
        [x] => 23
        [y] => 21.75
    )

[2] => Array
    (
        [x] => 14.25
        [y] => 21.875
    )

[3] => Array
    (
        [x] => 19.375
        [y] => 21.75
    )

[4] => Array
    (
        [x] => 9.125
        [y] => 21.875
    )
)

所有 X 值都是唯一的。我在网上搜索,发现这个功能可以使用,但这似乎不起作用:

 $result = array_map("unserialize", array_unique(array_map("serialize", $array)));    

【问题讨论】:

  • 如果整个元素必须是唯一的,而不是嵌套子数组中的值,则只能使用array_unique
  • 循环遍历数组,创建一个使用x 值作为键的新关联数组。对于每个元素,测试x是否已经在数组中;如果没有,添加它,否则跳过它。然后在结果上使用array_values得到最终的数组。

标签: php multidimensional-array array-unique


【解决方案1】:

只需循环遍历并找到唯一值:

$taken = array();

foreach($items as $key => $item) {
    if(!in_array($item['x'], $taken)) {
        $taken[] = $item['x'];
    } else {
        unset($items[$key]);
    }
}

每次第一次使用 x 值时,我们都会保存它 - 后续使用是来自数组的 unset

【讨论】:

    【解决方案2】:

    array_unique 比较字符串值,因此您可以创建对象(使用重载的__toString 函数)作为中间步骤。

    class XKeyObj {
        public $x;
        public $y;
    
        public function XKeyObj($x, $y) {
            $this->x = $x;
            $this->y = $y;
        }
    
        public function __toString() { return strval($this->x); }
    }
    
    function array_to_xKey($arr) { return new XKeyObj($arr['x'], $arr['y']); }
    function xKey_to_array($obj) { return array('x' => $obj->x, 'y' => $obj->y); }
    
    $input = array(
        array('x' => 0.5, 'y' => 23),
        array('x' => 23, 'y' => 21.75),
        array('x' => 14.25, 'y' => 21.875),
        array('x' => 19.375, 'y' => 21.75),
        array('x' => 9.125, 'y' => 21.875),
        array('x' => 23, 'y' => 19.625),
        array('x' => 19.375, 'y' => 19.625)
    );
    
    $output = array_map('xKey_to_array',
                        array_unique(array_map('array_to_xKey', $input)));
    
    print_r($output);
    

    结果:

    Array
    (
        [0] => Array
            (
                [x] => 0.5
                [y] => 23
            )
    
        [1] => Array
            (
                [x] => 23
                [y] => 21.75
            )
    
        [2] => Array
            (
                [x] => 14.25
                [y] => 21.875
            )
    
        [3] => Array
            (
                [x] => 19.375
                [y] => 21.75
            )
    
        [4] => Array
            (
                [x] => 9.125
                [y] => 21.875
            )
    
    )
    

    【讨论】:

      【解决方案3】:

      在对数组执行迭代检查时,in_array() 的性能拖累会随着临时查找数组大小的增加而逐渐恶化。

      考虑到这一点,使用临时关联键来识别后续重复项,以便可以在不断增长的结果变量上调用 !isset()。因为 php 数组是哈希映射,所以这种技术将始终优于 in_array()

      这些临时键有一个陷阱,专门适用于您的浮点类型值。 当浮点用作数组键时,php 将通过截断(“地板”而不是“舍入”将它们转换为整数”)。为避免这种不必要的副作用,请在临时键前面添加一个非数字字符(当然,连字符除外),以便浮点数变为字符串。

      代码:(Demo)

      $array = [
          ['x' => 0.5, 'y' => 23],
          ['x' => 23, 'y' => 21.75],
          ['x' => 14.25, 'y' => 21.875],
          ['x' => 19.375, 'y' => 21.75],
          ['x' => 9.125, 'y' => 21.875], 
          ['x' => 23, 'y' => 19.625],
          ['x' => 19.375, 'y' => 19.625],
      ];
      
      foreach ($array as $row) {
          if (!isset($result['#' . $row['y']])) {
              $result['#' . $row['y']] = $row;
          }
      }
      var_export(array_values($result));
      

      从 PHP7.4+ 开始享受空值合并赋值运算符 (Demo)

      foreach ($array as $row) {
          $result['#' . $row['y']] ??= $row;
      }
      var_export(array_values($result));
      

      输出:

      array (
        0 => 
        array (
          'x' => 0.5,
          'y' => 23,
        ),
        1 => 
        array (
          'x' => 23,
          'y' => 21.75,
        ),
        2 => 
        array (
          'x' => 14.25,
          'y' => 21.875,
        ),
        3 => 
        array (
          'x' => 23,
          'y' => 19.625,
        ),
      )
      

      附言如果将字符串或整数值作为临时键处理,则无需添加任何字符。如果您不关心从结果中删除临时键(因为您只是在“向下脚本”访问子数组值,那么您不需要在迭代后调用 array_values()

      【讨论】:

        【解决方案4】:
        array_unique(my_array, SORT_REGULAR)
        

        【讨论】:

        • 本期作者只对独特的x 值感兴趣。
        猜你喜欢
        • 2017-07-23
        • 2011-04-05
        • 1970-01-01
        • 1970-01-01
        • 2018-07-26
        • 2019-09-04
        • 1970-01-01
        • 2023-04-02
        • 1970-01-01
        相关资源
        最近更新 更多