2010-04-10 2 views
27

Sto cercando il modo più veloce per rimuovere i valori duplicati in una stringa separata da virgole.rimuovere il duplicato dalla stringa in PHP

Quindi la mia stringa è simile a questa;

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

Posso fare esplodere la stringa sui valori e quindi confrontare, ma penso che sarà lenta. che dire di preg_replace() sarà più veloce? Qualcuno lo ha fatto usando questa funzione?

+0

qual è la dimensione stimata di questi dati? –

risposta

102

Il codice più breve sarebbe:

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

Se è il più veloce ... non lo so, probabilmente è più veloce quindi loop in modo esplicito.

Riferimento: implode, array_unique, explode

+0

Grazie @Felix, che è eccellente, questo è quello che mi serviva, i valori massimi in una stringa sono 50. – Adnan

+0

@Adnan: con 50 valori questo non dovrebbe essere un gran problema :) –

+0

Funziona se multiplo di 2. Se no, fallisce. –

0

Trattare con: $string = 'one,two,one,five,seven,bag,tea';

Se si sta generando la stringa in qualsiasi punto "fino script", allora si dovrebbe essere l'eliminazione dei duplicati in cui si verificano.

Diciamo che si sta usando la concatenazione per generare la stringa del tipo:

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

... allora si avrebbe bisogno di estrarre valori unici da $string basato sul delimitatore (virgola), poi ri-implodere con la delimitatore.


vi suggerisco di progettare un metodo più diretto e negare i duplicati all'interno del ciclo foreach iniziale, in questo modo:

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 

Questo funziona perché i valori duplicati non sono mai permesso di esistere. Tutte le occorrenze successive verranno utilizzate per sovrascrivere l'occorrenza precedente. Questo filtro senza funzione funziona perché gli array potrebbero non avere due chiavi identiche nello stesso array (livello).

In alternativa, è possibile evitare la "sovrascrittura" di dati di array nel loop, chiamando if(!isset($array[$return_value])){$array[$return_value]=$return_value;} ma la differenza significa che si chiama la funzione isset() a ogni iterazione. Il vantaggio di utilizzare queste assegnazioni di chiavi associative è che il processo evita di utilizzare in_array() che è più lento di isset().

Detto questo, se si estraggono una colonna di dati da una matrice a 2 dimensioni come:

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

allora si potrebbe sfruttare la magia di array_column() senza un ciclo like this:

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

E infine, per chi è interessato alla micro-ottimizzazione, noterò che la singola chiamata di array_unique() è in realtà più lenta di una due metodi a due funzioni. Read here per maggiori dettagli.

La linea di fondo è, ci sono molti modi per eseguire questa operazione.explode->unique->implode può essere il metodo più conciso in alcuni casi se non si genera la stringa delimitata, ma non è probabile che sia il metodo più diretto o più veloce. Scegli tu stesso ciò che è meglio per il tuo compito.