2012-01-01 62 views
11

Así que esto es lo que me está molestando.PHP - Cómo comparar dos matrices y eliminar valores duplicados

Tengo dos matrices:

$array1 = array('[param1]' ,'demo' ,'[param2]' ,'some' ,'[param3]'); 
$array2 = array('value1' ,'demo' ,'value2' ,'some' ,'value3'); 

Ahora quiero comparar estos dos gama de, y eliminar todos los valores duplicados.
Al final quiero estas dos matrices, pero sin los valores 'demo' y 'algunos' en ellas.
Quiero eliminar todos los valores de array-s que tienen la misma clave de índice y valor.
Las matrices siempre tendrán la misma cantidad de valores e índices, solo quiero compararlas y eliminar las entradas que tengan la misma clave de índice y valor, de ambas.

que estoy haciendo algo como esto ahora:

$clean1 = array(); 
$clean2 = array();  

foreach($array1 as $key => $value) 
{ 
    if($value !== $array2[$key]) 
    { 
     $clean1[$key] = $value; 
     $clean2[$key] = $array2[$key]; 
    } 
} 

var_export($clean1); 
echo "<br />"; 
var_export($clean2); 

Y esto funciona! Pero me pregunto si hay alguna otra forma de hacerlo. ¿Tal vez sin usar el bucle foreach? ¿Hay una forma más elegante de hacer esto?

+3

¿Puedes definir qué "elegante" es para ti? No veo problemas aquí ... – nmagerko

+3

Esto siempre va a requerir una búsqueda lineal. En ese sentido, su solución es la más eficiente. – You

Respuesta

21
array_unique(array_merge($arr_1, $arr_2)); 

o puede hacerlo:

$arr_1 = array_diff($arr_1, $arr_2); 
$arr_2 = array_diff($arr_2, $arr_1); 

supongo ...

+0

Gracias! ¡El segundo es "elegante"! Pero, array_diff desconecta las claves de arr_1 que no están presentes en $ arr_2 y devuelve esa matriz con las claves que no están en orden.Y esto puede ser un problema para mí :(Necesito una nueva matriz que comience desde 0: S ¿Hay alguna manera de restablecer las teclas de matriz, si tengo claves como 0, 3, 7, puedo restablecerlas para que sean 1,2, 3? Si no, Il joust se queda con el primer bucle foreach. – Limeni

+4

$ arr_1 = array_values ​​($ arr_1); debería funcionar –

+0

yup bastante bueno para no iterar a través de los bucles pesados ​​de PHP estúpido xD –

4

Puede utilizar la función de array_diff en PHP que devolverá y matriz que contiene las claves que son los mismos entre el dos arreglos

$clean1 = array_diff($array1, $array2); 

http://php.net/manual/en/function.array-diff.php

+0

¡Gracias! ¡El segundo es "elegante"! , array_diff desconecta las claves de arr_1 que no están presentes en $ arr_2. Y esto puede ser un problema para mí :(Necesito una nueva matriz que empiece desde 0: S ¿Hay alguna forma de restablecer las claves de la matriz, si tengo claves como 0 , 3, 7, ¿puedo restablecerlos para ser 1,2,3? – Limeni

0

Desde $array1 y $array2 son siempre la misma longitud, se podría hacer algo como esto:

<?php 

    $array1 = array('[param1]' ,'demo' ,'[param2]' ,'some' ,'[param3]'); 
    $array2 = array('value1' ,'demo' ,'value2' ,'some' ,'value3'); 

    $map = array_combine($array1,$array2); 
    $map = array_filter($map ,function ($item) use (&$map) { 
     $keep_data = ($item != key($map)); 
     next($map); 
     return $keep_data; 
    }); 

    $clean1 = array_keys($map); 
    $clean2 = array_values($map); 

    var_export($clean1); 
    echo "<br />"; 
    var_export($clean2); 

?> 

¿Es mejor? Usted decide

+0

Whooh, para mí este es más complicado. Pensé que estaba haciendo overkill con foreach loop pero parece que esa es la mejor manera de hacerlo. menos para mí, para ti este podría ser más claro. ¡Gracias por el comentario! – Limeni

+1

Sí ... estoy de acuerdo ... y es 3 veces más lento también :) – Dancrumb

0

¿qué tal?

$res = array_diff($array1, $array_intersect($array1, $array2)); 
$reindexed = array_combine(array_keys($res), array_values($res)); 

o simplemente manera si no se necesitan claves

array_values(array_diff($array1, $array_intersect($array1, $array2))); 
1
$clean1 = array_diff($array1, $array2); 
$clean2 = array_diff($array2, $array1); 
$final_output = array_merge($clean1, $clean2); 
+1

Agregue algunas explicaciones para que la gente pueda saber por qué esto funciona – jou

0

Su solución es sin duda la más "elegante" (es decir, el más fácil de leer, y menor cantidad de código), pero aquí es otra solución que usa array_diff_ukey(). Conserva las claves y las pone en orden incremental, tal como lo solicitó.

$array1 = ['[param1]' ,'demo' ,'[param2]' ,'some' ,'[param3]']; 
$array2 = ['value1' ,'demo' ,'value2' ,'some' ,'value3']; 

$clean1 = $array1; 

$clean2 = array_diff_ukey(
    $array2, 
    $array1, 
    // Need to have "&" so the values get set. 
    function($a, $b) use (&$clean1, $array1, $array2) { 

     // Use isset() just in case keys are not identical 
     // or arrays are not the same length. 
     if (isset($array2[$b]) && $array2[$b] === $array1[$b]) { 
      unset($clean1[$b]); 
     } 

     return strcmp($array2[$a], $array1[$b]); 

}); 

print_r($clean1); 
print_r($clean2); 

y retorna este:

Array 
(
    [0] => [param1] 
    [2] => [param2] 
    [4] => [param3] 
) 
Array 
(
    [0] => value1 
    [2] => value2 
    [4] => value3 
) 

ejemplo here trabajo.

Cuestiones relacionadas