php: comprueba si una matriz tiene duplicados

Estoy seguro de que esta es una pregunta extremadamente obvia, y que hay una función que hace exactamente esto, pero parece que no puedo encontrarlo. En PHP, me gustaría saber si mi matriz tiene duplicados, lo más eficientemente posible. No quiero eliminarlos como lo hace array_unique , y particularmente no quiero ejecutar array_unique y compararlo con la matriz original para ver si son iguales, ya que esto parece muy ineficiente. En lo que respecta al rendimiento, la “condición esperada” es que la matriz no tenga duplicados.

Me gustaría poder hacer algo como

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

¿Hay alguna función obvia en la que no estoy pensando?
¿Cómo detectar valores duplicados en PHP array?
tiene el título correcto, y es una pregunta muy similar; sin embargo, si realmente lees la pregunta, está buscando los valores de la cuenta de la matriz.

Tu puedes hacer:

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

Sé que no estás detrás de array_unique() . Sin embargo, no encontrarás una función obvia mágica ni escribir será más rápido que hacer uso de las funciones nativas.

Propongo:

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

Ajuste el segundo parámetro de array_unique() para satisfacer sus necesidades de comparación.

⚡ SOLUCIÓN DE RENDIMIENTO ⚡

Si le interesan el rendimiento y las micro-optimizaciones, consulte este one-liner:

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

Descripción:

La función compara el número de elementos de la matriz en $input_array con elementos de array_flip ‘ed. Los valores se convierten en claves y adivinen qué: las claves deben ser únicas en las matrices asociativas, de modo que no se pierdan valores únicos y el número final de elementos sea inferior al original.

Como se dijo en las teclas de arreglos manuales, puede haber solo un tipo de int o string así que esto es lo que puede tener en los valores de matriz originales para comparar, de lo contrario, PHP comenzará a emitir con resultados inesperados.

PRUEBA PARA 10M REGISTROS ARRAY

  • La solución más votada: 14.187316179276s 🐌🐌🐌🐌🐌🐌🐌🐌🐌🐌🐌🐌🐌🐌
  • Solución aceptada: 2.0736091136932s 🐌🐌
  • Esta solución de respuesta: 0.14155888557434s 🐌 / 10

Caso de prueba:

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

Tenga en cuenta que la solución aceptada puede ser más rápida en ciertas condiciones cuando los valores no únicos están cerca del comienzo de una gran matriz.

Aquí está mi opinión sobre esto … después de algunas evaluaciones comparativas, encontré que este es el método más rápido para esto.

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

… o dependiendo de las circunstancias, esto podría ser marginalmente más rápido.

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

Será false si está duplicado o true si no hay duplicados.

¡Mantenlo simple, tonto! 😉

Simple OR lógica …

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

¡Saludos!

Encuentra esta solución útil

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

Después de ese conteo, el resultado es mayor que 0 que los duplicados únicos.

Dos formas de hacerlo de manera eficiente que puedo pensar:

  1. insertando todos los valores en algún tipo de hashtable y verificando si el valor que estás insertando ya está en él (tiempo O (n) esperado y espacio O (n))

  2. ordenar la matriz y luego verificar si las celdas adyacentes son iguales (O (nlogn) time y O (1) u O (n) espacio dependiendo del algoritmo de clasificación)

La solución de stormdrain probablemente sería O (n ^ 2), al igual que cualquier solución que implique escanear la matriz para cada elemento en busca de un duplicado

Como dijiste específicamente que no querías usar array_unique , voy a ignorar las otras respuestas a pesar de que probablemente sean mejores.

¿Por qué no usa array_count_values ​​() y luego verifica si la matriz resultante tiene algún valor mayor que 1?

Php tiene una función para contar las ocurrencias en la matriz http://www.php.net/manual/en/function.array-count-values.php

Estoy usando esto:

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

No sé si es el más rápido pero funciona bastante bien hasta ahora

Puedes hacerlo de esa manera también: Esto volverá verdadero si es único, en caso contrario devuelve falso.

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