php:检查数组是否有重复项

问题描述 投票:0回答:18

我确信这是一个非常明显的问题,并且有一个函数可以做到这一点,但我似乎找不到它。在 PHP 中,我想尽可能高效地知道我的数组中是否有重复项。我不想像

array_unique
那样删除它们,而且我也不想特别运行
array_unique
并将其与原始数组进行比较以查看它们是否相同,因为这看起来效率很低。就性能而言,“预期条件”是数组没有重复项。

我只是希望能够做类似的事情

if (no_dupes($array))
    // this deals with arrays without duplicates
else
    // this deals with arrays with duplicates

有什么我没有想到的明显功能吗?
如何检测 PHP 数组中的重复值?
有正确的标题,并且是一个非常相似的问题,但是如果您真正阅读了该问题,他正在寻找 array_count_values。

php arrays duplicates
18个回答
258
投票

我知道你不是在追求

array_unique()
。然而,您不会找到一个magicalobvious函数,编写一个函数也不会比使用原生函数更快。

我建议:

function array_has_dupes($array) {
   // streamline per @Felix
   return count($array) !== count(array_unique($array));
}

调整

array_unique()
的第二个参数来满足您的比较需求。


105
投票

性能优化的解决方案

如果您关心性能和微观优化,请查看以下一行:

function no_dupes(array $input_array) {
    return count($input_array) === count(array_flip($input_array));
}

描述:
函数将

$input_array
中的数组元素数量与 array_flip'ed 元素进行比较。值成为键,猜猜看是什么 - 键在关联数组中必须是唯一的,这样唯一的值不会丢失,并且最终元素数量低于原始数量。

警告:
手册中所述,数组键只能是

int
string
类型,因此这是您必须在原始数组值中进行比较的内容,否则PHP将开始casting并产生意外结果。有关这种边缘情况故障模式的示例,请参阅 https://3v4l.org/7bRXI

具有 1000 万条记录的数组的证明:

测试用例:

<?php

$elements = array_merge(range(1,10000000),[1]);

$time = microtime(true);
accepted_solution($elements);
echo 'Accepted solution: ', (microtime(true) - $time), 's', PHP_EOL;

$time = microtime(true);
most_voted_solution($elements);
echo 'Most voted solution: ', (microtime(true) - $time), 's', PHP_EOL;

$time = microtime(true);
this_answer_solution($elements);
echo 'This answer solution: ', (microtime(true) - $time), 's', PHP_EOL;

function accepted_solution($array){
 $dupe_array = array();
 foreach($array as $val){
  // sorry, but I had to add below line to remove millions of notices
  if(!isset($dupe_array[$val])){$dupe_array[$val]=0;}
  if(++$dupe_array[$val] > 1){
   return true;
  }
 }
 return false;
}

function most_voted_solution($array) {
   return count($array) !== count(array_unique($array));
}

function this_answer_solution(array $input_array) {
    return count($input_array) === count(array_flip($input_array));
}

请注意,当大数组的开头附近没有唯一值时,接受的解决方案在某些情况下可能会更快。


41
投票

你可以这样做:

function has_dupes($array) {
    $dupe_array = array();
    foreach ($array as $val) {
        if (++$dupe_array[$val] > 1) {
            return true;
        }
    }
    return false;
}

23
投票
$hasDuplicates = count($array) > count(array_unique($array)); 

如果重复,则为

true
;如果没有重复,则为
false


6
投票
$duplicate = false;

 if(count(array) != count(array_unique(array))){
   $duplicate = true;
}

5
投票

这是我对此的看法......经过一些基准测试,我发现这是最快的方法。

function has_duplicates( $array ) {
    return count( array_keys( array_flip( $array ) ) ) !== count( $array );
}

…或者根据具体情况,这可能会稍微快一些。

function has_duplicates( $array ) {
    $array = array_count_values( $array );
    rsort( $array );
    return $array[0] > 1;
}

1
投票

要从比较中删除所有空值,您可以添加

array_diff()

if (count(array_unique(array_diff($array,array("")))) < count(array_diff($array,array(""))))

参考来自here

的@AndreKR回答

0
投票

我能想到的两种有效的方法:

  1. 将所有值插入某种哈希表中,并检查要插入的值是否已在其中(预计 O(n) 时间和 O(n) 空间)

  2. 对数组进行排序,然后检查相邻单元格是否相等(O(nlogn) 时间和 O(1) 或 O(n) 空间,具体取决于排序算法)

stormdrain 的解决方案可能是 O(n^2),任何涉及扫描数组以查找重复元素的解决方案也是如此


0
投票

找到这个有用的解决方案

function get_duplicates( $array ) {
    return array_unique( array_diff_assoc( $array, array_unique( $array ) ) );
}

之后,如果大于 0,则计数结果大于重复项,否则唯一。


0
投票

保持简单,愚蠢! ;)

简单的 OR 逻辑...

function checkDuplicatesInArray($array){
    $duplicates=FALSE;
    foreach($array as $k=>$i){
        if(!isset($value_{$i})){
            $value_{$i}=TRUE;
        }
        else{
            $duplicates|=TRUE;          
        }
    }
    return ($duplicates);
}

问候!


0
投票

我正在用这个:

if(count($array)==count(array_count_values($array))){
    echo("all values are unique");
}else{
    echo("there's dupe values");
}

我不知道这是否是最快的,但到目前为止效果还不错


0
投票

我的另一个解决方案,这个与性能提升有关

$array_count_values = array_count_values($array);
if(is_array($array_count_values) && count($array_count_values)>0)
{
   foreach ($array_count_values as $key => $value)
   {
      if($value>1)
      {
        // duplicate values found here, write code to handle duplicate values            
      }
   }
}

0
投票

最短的一个

function no_dupes($array) {
    return $array === array_unique($array);
}

-1
投票

正如您明确表示您不想使用

array_unique
,我将忽略其他答案,尽管事实上它们可能更好。

为什么不使用 array_count_values() 然后检查结果数组是否有大于 1 的值?


-1
投票

Php 有一个函数可以计算数组中出现的次数 http://www.php.net/manual/en/function.array-count-values.php


-1
投票

你也可以这样做: 如果唯一,则返回 true,否则返回 false。

$nofollow = (count($modelIdArr) !== count(array_unique($modelIdArr))) ? true : false;

-1
投票

简单的解决方案,但速度相当快。

$elements = array_merge(range(1,10000000),[1]);

function unique_val_inArray($arr) {
    $count = count($arr);
    foreach ($arr as $i_1 => $value) {
        for($i_2 = $i_1 + 1; $i_2 < $count; $i_2++) {
            if($arr[$i_2] === $arr[$i_1]){
                return false;
            }
        }
    }
    return true;
}

$time = microtime(true);
unique_val_inArray($elements);
echo 'This solution: ', (microtime(true) - $time), 's', PHP_EOL;

速度 - [0.71]!


-1
投票
function hasDuplicate($array){
  $d = array();
  foreach($array as $elements) {
    if(!isset($d[$elements])){
      $d[$elements] = 1;
    }else{
      return true;
    } 
  } 
  return false;
}
© www.soinside.com 2019 - 2024. All rights reserved.