web-dev-qa-db-fra.com

supprimer les doublons de la chaîne PHP

Je cherche le moyen le plus rapide de supprimer les valeurs en double dans une chaîne séparée par des virgules.

Donc, ma chaîne ressemble à ceci;

$str = 'one,two,one,five,seven,bag,tea';

Je peux le faire exploser la chaîne en valeurs et ensuite comparer, mais je pense que ce sera lent. Qu'en est-il de preg_replace () sera-t-il plus rapide? Quelqu'un l'a fait en utilisant cette fonction?

29
Adnan

Le code le plus court serait:

$str = implode(',',array_unique(explode(',', $str)));

Si c'est le plus rapide ... Je ne sais pas, c'est probablement plus rapide que de boucler explicitement.

Référence: implode , array_unique , explode

117
Felix Kling

Traiter avec: $string = 'one,two,one,five,seven,bag,tea';

Si vous générez la chaîne à tout moment "script haut", vous devriez alors éliminer les doublons au fur et à mesure qu'ils se produisent.

Supposons que vous utilisiez la concaténation pour générer votre chaîne de la manière suivante:

$string='';
foreach($data as $value){
    $string.=(strlen($string)?',':'').some_func($value);
}

... vous devrez alors extraire les valeurs uniques de $string en fonction du délimiteur (virgule), puis réimploser avec le délimiteur.


Je suggère que vous conceviez une méthode plus directe et que vous refusiez les doublons à l'intérieur de la boucle foreach initiale, comme ceci:

foreach($data as $value){
    $return_value=some_func($value);  // cache the returned value so you don't call the function twice
    $array[$return_value]=$return_value;  // store the return value in a temporary array using the function's return value as both the key and value in the array.
}
$string=implode(',',$array);  // clean: no duplicates, no trailing commas

Cela fonctionne car les valeurs en double ne sont jamais autorisées. Toutes les occurrences suivantes seront utilisées pour écraser l'occurrence précédente. Ce filtre sans fonction fonctionne car les tableaux peuvent ne pas avoir deux clés identiques dans le même tableau (niveau).

Sinon, vous pouvez éviter "d'écraser" les données d'un tableau dans la boucle en appelant if(!isset($array[$return_value])){$array[$return_value]=$return_value;}, mais la différence signifie que vous appelez la fonction isset() à chaque itération. L'avantage d'utiliser ces affectations de clés associatives est que le processus évite d'utiliser in_array() qui est plus lent que isset().

Cela dit, si vous extrayez une colonne de données d'un tableau à 2 dimensions comme:

$string='';
foreach($data as $value){
    $string.=(strlen($string)?',':'').$value['Word'];
}

Ensuite, vous pouvez exploiter la magie de array_column() sans boucle comme ceci :

echo implode(',',array_column($str,'Word','Word'));

Et enfin, pour ceux qui s'intéressent à la micro-optimisation, notons que l'appel unique de array_unique() est en réalité plus lent que quelques méthodes à deux fonctions. Lisez ici pour plus de détails.

En bout de ligne, il existe de nombreuses façons d’exécuter cette tâche. explode->unique->implode peut être la méthode la plus concise dans certains cas si vous ne générez pas la chaîne délimitée, mais il est peu probable que ce soit la méthode la plus directe ou la plus rapide. Choisissez vous-même ce qui convient le mieux à votre tâche.

0
mickmackusa