我确信这是一个非常明显的问题,并且有一个函数正是这样做的,但我似乎无法找到它。在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。
答案 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中所述,数组键只能是int
或string
的类型,所以这是你可以在原始数组值中进行比较,否则PHP将启动{{3意外结果。
测试用例:
<?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)
我能想到的两种有效方法:
将所有值插入某种散列表并检查您插入的值是否已经在其中(预期的O(n)时间和O(n)空间)
对数组进行排序,然后根据排序算法检查相邻单元格是否相等(O(nlogn)时间和O(1)或O(n)空间)
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的值?