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

时间:2010-06-29 23:52:10

标签: php arrays duplicates

我确信这是一个非常明显的问题,并且有一个函数正是这样做的,但我似乎无法找到它。在PHP中,我想知道我的数组是否有重复,尽可能高效。我不想像array_unique那样删除它们,我不想特别想运行array_unique并将它与原始数组进行比较,看它们是否相同,因为这看起来非常效率低下。就性能而言,“预期条件”是阵列没有重复。

我希望能够做一些像

这样的事情
if (no_dupes($array))
    // this deals with arrays without duplicates
else
    // this deals with arrays with duplicates

我有没有想到的明显功能?
How to detect duplicate values in PHP array?
有正确的标题,并且是一个非常相似的问题,但如果你真的读过这个问题,他正在寻找array_count_values。

17 个答案:

答案 0 :(得分:180)

我知道你不是在array_unique()之后。但是,你不会找到一个神奇的 明显的函数,写一个函数也不会比使用原生函数更快。

我建议:

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

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

答案 1 :(得分:46)

⚡性能解决方案⚡

如果你关心性能和微观优化,请检查这个单线:

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

说明

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

manual中所述,数组键只能是intstring的类型,所以这是你可以在原始数组值中进行比较,否则PHP将启动{{3意外结果。

10M记录阵列的证明

  • 投票最多的解决方案:14.187316179276s
  • 接受的解决方案:2.0736091136932s
  • 此答案解决方案:0.14155888557434s / 10

测试用例:

<?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));
}

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

答案 2 :(得分:37)

你可以这样做:

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

答案 3 :(得分:4)

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

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

答案 4 :(得分:3)

count($array) > count(array_unique($array)); 

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

答案 5 :(得分:2)

保持简单,愚蠢! ;)

简单OR逻辑......

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

问候!

答案 6 :(得分:2)

$duplicate = false;

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

答案 7 :(得分:1)

找到这个有用的解决方案

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

如果计数结果大于0,则重复其他唯一。

答案 8 :(得分: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            
      }
   }
}

答案 9 :(得分:0)

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

  1. 将所有值插入某种散列表并检查您插入的值是否已经在其中(预期的O(n)时间和O(n)空间)

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

  3. stormdrain的解决方案可能是O(n ^ 2),任何涉及扫描数组搜索每个元素的解决方案都是O(n ^ 2)

答案 10 :(得分:0)

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

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

参考来自 here 的 @AndreKR 回答

答案 11 :(得分:0)

function hasDuplicate($array){
  $d = array();
  foreach($array as $elements) {
    if(!isset($d[$elements])){
      $d[$elements] = 1;
    }else{
      return true;
    } 
  } 
  return false;
}

答案 12 :(得分:0)

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

$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]!

答案 13 :(得分:0)

你也可以这样做: 如果unique else返回false,则返回true。

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

答案 14 :(得分:0)

我用这个:

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

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

答案 15 :(得分:0)

Php具有计算数组http://www.php.net/manual/en/function.array-count-values.php

中出现次数的函数

答案 16 :(得分:0)

正如你明确表示你不想使用array_unique我会忽略其他答案,尽管它们可能更好。

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