web-dev-qa-db-fra.com

php: vérifier si un tableau a des doublons

Je suis sûr que c'est une question extrêmement évidente et qu'il existe une fonction qui fait exactement cela, mais je n'arrive pas à la trouver. En PHP, j'aimerais savoir si mon tableau contient des doublons, aussi efficacement que possible. Je ne veux pas les supprimer comme le fait array_unique, et je ne veux pas particulièrement exécuter array_unique et le comparer au tableau d'origine pour voir s'ils sont identiques, cela semble très inefficace. En ce qui concerne les performances, la "condition attendue" est que le tableau ne comporte pas de doublons.

J'aimerais juste pouvoir faire quelque chose comme

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

Y a-t-il une fonction évidente à laquelle je ne pense pas?
Comment détecter les valeurs en double dans le tableau PHP?
a le bon titre et est une question très similaire, cependant si vous lisez réellement la question, il cherche array_count_values.

48
Mala

Tu peux faire: 

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

Je sais que vous n'êtes pas après array_unique(). Cependant, vous ne trouverez pas un magique La fonction évident et l'écriture ne seront pas plus rapides que l'utilisation des fonctions natives.

Je propose:

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

Ajustez le deuxième paramètre de array_unique() pour répondre à vos besoins en matière de comparaison.

172
Jason McCreary

SOL SOLUTION DE PERFORMANCE

Si vous vous souciez de la performance et des micro-optimisations, vérifiez ce one-liner:

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

La description:

La fonction compare le nombre d'éléments de tableau dans $input_array avec les éléments array_flip 'ed. Les valeurs deviennent des clés et devinent quoi - les clés doivent être uniques dans les tableaux associatifs afin de ne pas perdre de valeurs uniques et que le nombre final d'éléments soit inférieur à celui d'origine.

Comme indiqué dans manual , les clés de tableau ne peuvent contenir que le type int ou string, c'est donc ce que vous pouvez avoir dans les valeurs de tableau d'origine à comparer, sinon PHP démarrera transter avec des résultats inattendus.

PREUVE POUR 10M RECORDS ARRAY

  • La plupart ont voté: 14.187316179276s ???????????????????????????????????????????? ????????????
  • Solution acceptée: 2.0736091136932s ????????
  • Cette solution de réponse: 0.14155888557434s ????/10

Cas de test:

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

Notez que la solution acceptée peut être plus rapide dans certaines conditions lorsque des valeurs non uniques se rapprochent du début d'un grand tableau.

42
s3m3n

Voici ce que je pense de ceci… Après quelques analyses comparatives, j'ai trouvé que c'était la méthode la plus rapide pour cela.

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

… Ou selon les circonstances, cela pourrait être légèrement plus rapide.

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

Sera false s'il y a des doublons ou true s'il n'y en a pas.

3
Andrew

Restez simple, idiot! ;)

Simple logique OR ... 

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

Cordialement!

2
Miles Bennet
$duplicate = false;

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

Trouvez cette solution utile

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

Après ce nombre, le résultat est supérieur à 0, puis les doublons sont uniques.

1
Muhammad Raheel

J'utilise ceci:

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

Je ne sais pas si c'est le plus rapide mais ça marche plutôt bien jusqu'à présent

0
Abraham Romero

Php a une fonction pour compter les occurrences dans le tableau http://www.php.net/manual/en/function.array-count-values.php

0
mazgalici

Vous pouvez le faire comme ça aussi: Cela retournera true si unique sinon retournera false.

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

Deux manières de le faire efficacement auxquelles je peux penser:

  1. insérer toutes les valeurs dans une sorte de table de hachage et vérifier si la valeur que vous insérez y est déjà (durée O(n) et espace O(n) prévus)

  2. trier le tableau, puis vérifier si les cellules adjacentes sont égales (temps O(nlogn) et espace O(1) ou O(n) en fonction de l'algorithme de tri)

la solution de stormdrain serait probablement O (n ^ 2), de même que toute solution impliquant le balayage du tableau pour chaque élément recherchant un doublon.

0
Bwmat

Comme vous l'avez spécifiquement dit, vous ne voulez pas utiliser array_unique, je vais ignorer les autres réponses, même si elles sont probablement meilleures.

Pourquoi ne pas utiliser array_count_values ​​() puis vérifier si le tableau résultant a une valeur supérieure à 1?

0
delete me