2009-09-10 18 views
15

¿Existe una función incorporada para PHP para comprobar si dos matrices contienen los mismos valores (orden no importante?).PHP: Función incorporada para verificar si dos valores de matriz son iguales (Ignorar el orden)

Por ejemplo, yo quiero una función que devuelve mí cierto para las dos entradas siguientes:

array('4','5','2') 
array('2','4','5') 

Editar: Podría haber ordenado las dos matrices y compararlas, pero como soy un tipo tan perezoso , Aún preferiría un trazador de líneas que pueda sacar y usar.

Respuesta

29

array_diff parece una opción:

function array_equal($a1, $a2) { 
    return !array_diff($a1, $a2) && !array_diff($a2, $a1); 
} 

o como un oneliner en el código:

if(!array_diff($a1, $a2) && !array_diff($a2, $a1)) doSomething(); 
+3

Puedes usar 'empty' solo con varliables. – Gumbo

+0

gumbo: no, puedes usarlo en arreglos muy bien. tomado de : "Las siguientes cosas se consideran vacías: # array() (una matriz vacía)" – knittl

+3

Gumbo tiene razón. No puede usar el valor de retorno de una función con 'empty'. Eso es lo que en realidad estaba diciendo. Tienes que almacenar el valor de retorno de 'array_diff' en una variable de temperatura o simplemente usar el operador not:' return! Array_diff ($ a1, $ a2) '. –

7

La mejor solución es ordenar tanto la matriz y luego compararlas:

$a = array('4','5','2'); 
$b = array('2','4','5'); 
sort($a); 
sort($b); 
var_dump($a === $b); 

En función:

function array_equal($a, $b, $strict=false) { 
    if (count($a) !== count($b)) { 
     return false; 
    } 
    sort($a); 
    sort($b); 
    return ($strict && $a === $b) || $a == $b; 
} 

Aquí hay otro algoritmo de búsqueda de cada elemento de Un si es en B:

function array_equal($a, $b, $strict=false) { 
    if (count($a) !== count($b)) { 
     return false; 
    } 
    foreach ($a as $val) { 
     $key = array_search($val, $b, $strict); 
     if ($key === false) { 
      return false; 
     } 
     unset($b[$key]); 
    } 
    return true; 
} 

Pero eso tiene una complejidad de O (n^2). Entonces es mejor que uses el método de clasificación.

+0

como soy un tipo tan perezosa, todavía prefiere una sola línea que puedo sacar y usar. – Graviton

+2

@Ngu Soon Hui - ¿Así que envuelve el código de Gumbo en una función (array_equals ($ arr1, $ arr2))? – karim79

+2

Sería útil si el votante de abajo comentara por qué votó mi respuesta. – Gumbo

2

Puede usar array_diff.

$a = array('4','5','2'); 
$b = array('2','4','5'); 

if(count(array_diff($a, $b)) == 0) { 
    // arrays contain the same elements 
} else { 
    // arrays contain different elements 
} 

Sin embargo, un problema con este enfoque es que las matrices pueden contener elementos duplicados y aun así coincidir.

+1

¿Alguien conoce los detalles sobre la diferencia de rendimiento entre un diff y un género en php? – Kazar

+2

'if (array_diff ($ a, $ b)) {}' haría. matriz vacía evaluar a falso. – SilentGhost

+0

Usar 'array_diff' es fácil. Pero requiere espacio extra (O (* n *)) ya que se crea una matriz adicional donde se almacenan los elementos de * A *, que no son también elementos de * B *. – Gumbo

3

El método array_diff() anterior no funcionará. Manual

de php.net dice que array_diff() hace esto:

"Devuelve una matriz que contiene todas las entradas de matriz1 que no están presentes en ninguna de las otras matrices."

Así que la array_diff() método real sería:

function array_equal($array1, $array2) 
{ 
    $diff1 = array_diff($array1, $array2); 
    $diff2 = array_diff($array2, $array1); 

    return 
    (
     (count($diff1) === 0) && 
     (count($diff2) === 0) 
    ); 
} 

Sin embargo voy con el método para ordenar: D

+0

+1 esa es una mejor manera de hacerlo . Encontré ese problema hoy y terminé usando '! Array_diff ($ a, $ b) &&! Array_diff ($ b, $ a)'. No es la mejor solución, pero funciona. – Weboide

+0

Una nota al margen: aunque esto está fuera de la cuestión de OP, vale la pena recordar que el uso de 'array_diff()' (y similar a 'array_intersect()' fallará ** en arreglos multidimensionales ** (aviso de PHP: _Array to string conversion_), mientras que el uso de operadores de matriz simple de '==' y '===' funcionará en tales matrices sin ningún problema. – trejder

0

Puede utilizar array_intersect() en lugar de array_diff():

$a = array('4','5','2'); 
$b = array('2','4','5'); 
$ca = count($a); 
$cb = count($b); 
$array_equal = ($ca == $cb && $ca == count(array_intersect($a, $b))); 

En cuanto al rendimiento. solución, donde dos factores son importantes:

  • cuanto más a menudo las matrices coinciden, más array_intersect() es rápido.
  • cuantas más matrices son grandes (más de 10 valores), más array_intersect() es más rápido.

Dependiendo de estos factores, un método puede ser dos o tres veces más rápido que el otro. Para arreglos grandes con pocas (o ninguna) combinación de combinaciones, o para arreglos pequeños con muchas coincidencias, ambos métodos son equivalentes.

Sin embargo, el método de ordenación es siempre más rápido, excepto en el caso de arreglos pequeños con pocas o ninguna combinación correspondiente. En este caso, el método array_diff() es un 30% más rápido.

+0

Aviso de formato: usó HTML mal escrito en lugar de Markdown (fijo) y parece que no le gustan las letras mayúsculas al principio de cada sección (corregidas). ¡Entonces, en general, debería menospreciar tu pereza! :] Pero, por otro lado, brindó una respuesta excepcional e interesante, ¡así que está bien! :] – trejder

1

Solo tiene que comparar una vía con array_diff() y usar count() para la relación invertida.

if (count($a1) == count($a2) && !array_diff($a1, $a2)) { 
    // equal arrays 
} 
0

Si las matrices que se comparan consistir sólo cadenas y/o enteros, array_count_values le permite comparar las matrices rápidamente (en O(n) tiempo vs O(n log n) para la clasificación) verificando que ambas matrices contienen los mismos valores y que cada el valor ocurre el mismo número de veces en ambas matrices.

if(array_count_values($a1) == array_count_values($a2)) { 
    //arrays are equal 
} 
Cuestiones relacionadas