2010-04-10 50 views
27

Estoy buscando la forma más rápida de eliminar valores duplicados en una cadena separada por comas.eliminar el duplicado de una cadena en PHP

Así que mi cadena se ve así;

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

Puedo hacerlo explotando la cadena de valores y luego comparar, pero creo que será lento. ¿qué pasa con preg_replace() será más rápido? ¿Alguien lo hizo usando esta función?

+0

¿Cuál es el tamaño estimado de estos datos? –

Respuesta

102

El código más corto sería:

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

Si es el más rápido ... No sé, es probable que sea más rápido que un bucle de forma explícita.

Referencia: implode, array_unique, explode

+0

Gracias @Felix, eso es excelente, eso es lo que necesitaba, los valores máximos en una cadena son 50. – Adnan

+0

@Adnan: con 50 valores esto no debería ser un gran problema :) –

+0

Funciona si es múltiplo de 2. Si no, falla –

0

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

Si va a generar la cadena en cualquier punto "a la escritura", entonces debería ser la eliminación de duplicados a medida que ocurren.

Digamos que usted está utilizando concatenación para generar su cadena como:

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

... entonces deberá extraer valores únicos de $string basado en el delimitador (coma), a continuación, volver a implosionar con el delimitador.


Sugiero que el diseño de un método más directo y negar duplicados dentro del bucle foreach inicial, así:

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 

Esto funciona porque los valores duplicados no se les permite existir. Todas las ocurrencias subsecuentes se usarán para sobrescribir la ocurrencia anterior. Este filtro sin función funciona porque las matrices pueden no tener dos claves idénticas en la misma matriz (nivel).

Como alternativa, puede evitar "sobreescribir" datos de matriz en el ciclo, llamando al if(!isset($array[$return_value])){$array[$return_value]=$return_value;}, pero la diferencia significa llamar a la función isset() en cada iteración. La ventaja de utilizar estas asignaciones de clave asociativas es que el proceso evita el uso de in_array() que es más lento que isset().

Dicho todo esto, si usted está extrayendo una columna de datos de una matriz de 2 dimensiones como:

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

entonces se podría aprovechar la magia de array_column() sin un bucle like this:

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

Y, por último, para aquellos interesados ​​en la micro-optimización, señalaré que la única llamada de array_unique() es en realidad más lenta que af ew métodos de dos funciones. Read here para más detalles.

La conclusión es que hay muchas maneras de realizar esta tarea.explode->unique->implode puede ser el método más conciso en algunos casos si no está generando la cadena delimitada, pero no es probable que sea el método más directo o más rápido. Elige por ti mismo lo que es mejor para tu tarea.

Cuestiones relacionadas