PHP:检查一个数组是否有重复

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

我只想能够做一些类似的事情

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

有没有明显的function我没有想到?
如何检测PHP数组中的重复值?
是一个非常相似的问题,但是如果你阅读这个问题,他正在寻找array_count_values。

你可以做:

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

我知道你不是在array_unique() 。 然而,你不会发现一个神奇的 明显的function,也不会写一个比使用本地函数更快。

我提议:

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

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

⚡性能解决scheme⚡

如果你关心性能和微观优化检查这一行:

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

描述:

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

正如在手动数组中所说的,键只能是int或者stringtypes,所以你可以在原始数组值中进行比较,否则PHP将会以非预期的结果开始投射 。

10Mloggingarrays的certificate

  • 大多数投票解决scheme:14.187316179276s🐌🐌🐌🐌🐌🐌🐌🐌🐌🐌🐌🐌🐌🐌
  • 接受的解决scheme:2.0736091136932s🐌🐌
  • 这个答案解决scheme:0.14155888557434s🐌/ 10

testing用例:

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

请注意,如果不是唯一值接近巨大数组的开始位置,则在某些情况下接受的解决scheme可能会更快。

这是我的这个…在一些基准testing后,我发现这是最快的方法。

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

保持简单,愚蠢! ;)

简单的OR逻辑…

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

问候!

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

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

find有用的解决scheme

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

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

有两种方法可以有效地做到这一点:

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

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

stormdrain的解决scheme可能是O(n ^ 2),任何解决scheme都涉及扫描数组中的每个元素search重复

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

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

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

我正在使用这个:

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

我不知道这是否是最快的,但迄今为止效果还不错

你也可以这样做:这将返回true,否则返回false。

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