【问题标题】:How to remove values from an array if occurring more than one time?如果出现多次,如何从数组中删除值?
【发布时间】:2017-11-23 01:03:17
【问题描述】:

我需要从数组中删除在数组中出现多次的值。

例如:

$value = array(10,10,5,8);

我需要这个结果:

$value = array(5,8);

php有内置函数吗?

我试过了,但这不会返回我的预期结果:

$unique = array_unique($value);
$dupes = array_diff_key($value, $unique);

【问题讨论】:

  • 查看PHP array functions,然后您应该能够自己想出一些东西。如果您在实现您的想法时遇到具体问题,请向我们展示您的代码并提出具体问题。
  • $unique = array_unique($value); $dupes = array_diff_key($value, $unique); - 我试过了,但这不会返回我的预期结果

标签: php arrays duplicates filtering


【解决方案1】:

如果您愿意,可以使用数组函数并放弃 foreach 循环:

这是一个单行:

代码:

$value = [10, 10, 5, 8];
var_export(array_keys(array_intersect(array_count_values($value),[1])));

作为多行:

var_export(
    array_keys(
        array_intersect(
            array_count_values($value),
            [1]
        )
    )
);

输出:

array (
  0 => 5,
  1 => 8,
)

这将值计数为一个数组,然后使用array_intersect() 仅保留出现一次的值,然后将键转换为零索引数组的值。

上面的 sn-p 与@modsfabio 和@axiac 的答案相同。我的 sn-p 的唯一优势是简洁。他们的解决方案可能会优于我的解决方案,但在相对较小的数据集上判断速度可能会浪费开发时间。对于处理相对较大数据集的任何人,请自行进行基准测试以找到最有效的技术。


为了获得最低的计算/时间复杂度,请使用单个循环,并在您进行迭代时根据需要有条件地填充查找数组和unset()

代码:(Demo) (Crosslink to my CodeReview answer)

$values = [10, 10, 5, 8];

$found = [];
foreach ($values as $index => $value) {
    if (!isset($found[$value])) {
        $found[$value] = $index;
    } else {
        unset($values[$index], $values[$found[$value]]);
    }
}
var_export($values);
// [2 => 5, 3 => 8]

几点说明:

  1. 如果处理浮点值,使用将值存储为键的技术(就像我所有的 sn-ps 所做的那样),那么结果可能不正确,因为 php 在用作键时会将浮点数更改为整数。
  2. PHP 搜索键的速度始终比搜索值快得多。

【讨论】:

    【解决方案2】:

    你可以使用 foreach 循环 和 array_diff() 函数:

    $value=array(10,10,5,8);
    $duplicated=array();
    foreach($value as $k=>$v)
    {
    if($kt=array_search($v,$value))!==false and 
    $k!=$kt)
    {if (count(array_keys($array, $value)) > 1) 
    {
     /* Execute code */
    }
    unset($value[$kt];$duplicated[]=$v;
    }
    }
    
    $result=array_diff($values,$duplicated);
    print_r($result);
    

    输出

    数组([2]=>5[3]=>8)

    【讨论】:

    • 这个答案没有经过测试,有语法错误,解释得不好,而且不起作用。
    【解决方案3】:

    您需要使用array_count_values()array_search()unset() 函数。

    <?php
    $value = array(10,10,5,8);
    echo '<pre>';print_r($value);echo '</pre>';
    $cnt = array_count_values($value);
    $dup = array();
    foreach ($cnt as $k => $repeated) {
        if ($repeated > 1) {
            if(($key = array_search($k, $value)) !== false) {
                unset($value[$key]);
            }
        }
    }
    echo '<pre>';print_r($cnt);echo '</pre>';
    echo '<pre>';print_r($value);echo '</pre>';
    ?>
    

    Demo

    【讨论】:

    • 这并没有给出想要的结果
    • @modsfabio,感谢您的宝贵意见。我一定会调查的。
    • 观看这个 sn-p 失败:3v4l.org/I9rQY 代码逻辑简直是有缺陷。
    【解决方案4】:

    您可以使用array_count_values()foreach 循环来执行此操作:

    <?php
    
    $input = array(10,10,5,8);
    $output = array();
    
    foreach(array_count_values($input) as $value => $count)
    {
        if($count == 1)
        {
            $output[] = $value;
        }
    }
    
    var_dump($output);
    

    输出:

    array(2) {
      [0]=>
      int(5)
      [1]=>
      int(8)
    }
    

    示例:https://eval.in/819461

    【讨论】:

      【解决方案5】:

      一种可能的方法:

      $value = array(10,10,5,8);
      $output = array_keys(
          array_filter(
              array_count_values($value),
              function ($count) {
                  return $count == 1;
              }
          )
      )
      

      array_count_values() 生成一个数组,该数组将$value 中的每个唯一值与它在数组中出现的次数相关联。

      array_filter() 在这个结果中只保留在原始数组中只出现一次的条目(键)。

      array_keys() 产生所需的结果。

      【讨论】:

        【解决方案6】:

        我会使用array_count_values 来获取一个数组,其中包含每个元素在数组中出现的频率。然后从原始数组中删除所有多次出现的元素。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-09-27
          • 2021-10-10
          • 1970-01-01
          相关资源
          最近更新 更多