¿Cómo eliminar valores de dos matrices que tienen la misma clave y valor?

4 minutos de lectura

avatar de usuario
Limeni

Tengo dos matrices:

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

Quiero comparar estas dos matrices y eliminar todos los valores duplicados.
Al final, quiero estas dos matrices pero sin valores ‘demo’ y ‘algunos’ en ellas.
Quiero eliminar todos los valores de las matrices que tienen la misma clave de índice y valor.
Las matrices siempre tendrán la misma cantidad de valores e índices, solo quiero compararlos y eliminar las entradas que tienen la misma clave de índice y valor, de ambos.

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 hacer esto. ¿Quizás sin usar el bucle foreach?

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

    – Tú

    1 de enero de 2012 a las 1:05

  • Esta pregunta no está clara porque el ejemplo mínimo reproducible es de muy mala calidad. La declaración lógica de I want to remove all values from array-s that have the same index key and value. no está bien representado en los datos de la muestra. Esto ha llevado a la publicación de respuestas que no respetan adecuadamente las relaciones índice-valor.

    – mickmackusa

    18 de agosto de 2020 a las 22:40

Su solución es definitivamente la más “elegante” (es decir, la más fácil de leer y la menor cantidad de código), pero aquí hay otra solución que usa array_diff_ukey(). Conserva las claves y las coloca en orden incremental, 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);

Devolverá esto:

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

ejemplo de trabajo aquí.

  • Incluso si todos los valores en ambas matrices son cadenas, este enfoque no es confiable. 3v4l.org/uIrAE y luego los valores que no son cadenas también causan problemas 3v4l.org/np0ag. En el contexto de array_diff_ukey() (y todos sus u primos), $a no se refiere exclusivamente a las claves del primer parámetro de matriz y $b no se refiere a las claves del segundo parámetro de matriz.

    – mickmackusa

    hace 2 días


  • He aquí un ejemplo donde $array2 tiene un elemento extra. El elemento adicional tiene una clave de 6. El 6 se puede encontrar como ambos $a y como $b mientras que PHP está ordenando el algoritmo y comparando. 3v4l.org/V5gYq Incluso después de eliminar los casos marginales, esta respuesta falla. 3v4l.org/81g4P

    – mickmackusa

    hace 2 días


  • Whooh, para mí este es más complicado. Pensé que estaba exagerando con el bucle foreach, pero parece que esa es la mejor manera de hacerlo. Al menos para mí, para ti esto podría ser más claro. ¡Gracias por el comentario!

    – Limani

    1 de enero de 2012 a las 1:31

  • Sí… de acuerdo… y también es 3 veces más lento 🙂

    – Dancrumb

    2 de enero de 2012 a las 16:57

  • Esta respuesta no es estable porque destruye valores duplicados en $array1 llamando array_combine() en el primer paso. $map no puede contener claves duplicadas, por lo que se pierden datos vitales. Este enfoque no solo es “más complicado”, sino que corre un riesgo muy real de generar resultados incorrectos. 3v4l.org/MdQ83

    – mickmackusa

    hace 2 días

avatar de usuario
krejcon3

¿qué pasa?

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

o simplemente manera si no se necesitan llaves

array_values(array_diff($array1, array_intersect($array1, $array2)));

  • Esta respuesta es incorrecta porque eliminará valores incluso si las claves son diferentes. La pregunta preguntaba cómo eliminar elementos que tienen la misma clave y valor.

    – Darman

    hace 2 días

avatar de usuario
tylerh

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

o puedes hacer:

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

  • Esta respuesta es incorrecta porque eliminará valores incluso si las claves son diferentes. La pregunta preguntaba cómo eliminar elementos que tienen la misma clave y valor.

    – Darman

    hace 2 días

avatar de usuario
mizhar rajá

$clean1 = array_diff($array1, $array2); 
$clean2 = array_diff($array2, $array1); 
$final_output = array_merge($clean1, $clean2);

  • este código no elimina elementos duplicados en la matriz

    –Marvin Collins

    21 de diciembre de 2018 a las 17:06

  • Esta respuesta es incorrecta porque eliminará valores incluso si las claves son diferentes. La pregunta preguntaba cómo eliminar elementos que tienen la misma clave y valor.

    – Darman

    hace 2 días

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad