代码之家  ›  专栏  ›  技术社区  ›  Mala

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

  •  49
  • Mala  · 技术社区  · 14 年前

    array_unique 是的,我也不想跑 数组\u唯一

    我只想做一些

    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?

    13 回复  |  直到 7 年前
        1
  •  39
  •   BritishWerewolf TalOrlanczyk    7 年前

    你可以做:

    function has_dupes($array) {
        $dupe_array = array();
        foreach ($array as $val) {
            if (++$dupe_array[$val] > 1) {
                return true;
            }
        }
        return false;
    }
    
        2
  •  230
  •   Jason McCreary    9 年前

    我知道你不想 array_unique() 明显的

    我提议:

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

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

        3
  •  80
  •   s3m3n    7 年前

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

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

    函数用于比较 $input_array array_flip 'ed元素。值成为键并猜测-键在关联数组中必须是唯一的,这样就不会丢失唯一的值,并且最终的元素数比原始的要少。

    如前所述 manual 数组键只能是 int string 所以这是您可以在原始数组中比较的值,否则PHP将启动 casting 结果出乎意料。

    10M记录数组的证明

    • 投票最多的解决方案:14.187316179276s
    • 此答案解决方案:0.141558885557434s/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));
    }
    

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

        4
  •  18
  •   Andrew    5 年前
    $hasDuplicates = count($array) > count(array_unique($array)); 
    

    true 如果重复,或 false 如果没有重复。

        5
  •  6
  •   Ankita Mehta    5 年前
    $duplicate = false;
    
     if(count(array) != count(array_unique(array))){
       $duplicate = true;
    }
    
        6
  •  4
  •   micadelli    11 年前

    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;
    }
    
        7
  •  2
  •   웃웃웃웃웃    10 年前

    保持简单,傻瓜!;)

    简单或逻辑。。。

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

        8
  •  0
  •   Bwmat    14 年前

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

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

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

    Stormdain的解决方案可能是O(n^2),任何涉及扫描数组中每个元素以搜索重复项的解决方案都是如此

        9
  •  0
  •   Muhammad Raheel    11 年前

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

    之后,如果大于0,则计数结果将比其他唯一项重复。

        10
  •  0
  •   Abraham Romero    9 年前

    我用这个:

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

        11
  •  0
  •   Prasad Patel    3 年前

    array_diff()

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

    here

        12
  •  0
  •   Prasad Patel    3 年前

    我还有一个解决方案,这与性能改进有关

    $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            
          }
       }
    }
    
        13
  •  -1
  •   delete me delete me    14 年前

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

    你为什么不用 array_count_values()

        14
  •  -1
  •   mazgalici    10 年前

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

        15
  •  -1
  •   Lakhan    8 年前

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

    $nofollow = (count($modelIdArr) !== count(array_unique($modelIdArr))) ? true : false;
    
        16
  •  -1
  •   Юрий Светлов    5 年前

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

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

        17
  •  -1
  •   lilHar    5 年前
    function hasDuplicate($array){
      $d = array();
      foreach($array as $elements) {
        if(!isset($d[$elements])){
          $d[$elements] = 1;
        }else{
          return true;
        } 
      } 
      return false;
    }