¿Cómo devolver una matriz con valores verdaderos/falsos comparando 2 matrices?

4 minutos de lectura

avatar de usuario
Luqsus

Estoy tratando de generar una matriz como resultado de la comparación de 2 matrices: la primera matriz tiene más elementos como:

array1: {
    0 => "car1"
    1 => "car2"
    2 => "car3"
    3 => "car4"
    4 => "car5"
}

y la segunda matriz no tiene todos los elementos:

array2: {
    0 => "car1"
    1 => "car4"
    2 => "car5"
}

Entonces, hay todas las categorías posibles (matriz1) y categorías asignadas a la publicación (matriz2) (es una cosa de WordPress).
Estoy tratando de comparar esas matrices (pero no con array_diff() función que me dio valores de elementos en lugar de booleanos) y obtener el resultado como verdadero/falso. Entonces quiero comparar cada valor de las matrices y generar mapa de matriz o tal vez usando array_combine() función para obtener una matriz como esa:

result_array: {
    "car1": true,
    "car2": false,
    "car3": false
}

etc…
Es importante que la matriz de salida tenga todas las categorías y sus resultados (verdadero, falso) para la publicación.
¿Hay alguna manera simple de hacerlo o tal vez es una función que podría usar?

avatar de usuario
nombre_de_usuario_aleatorio

¡Las matrices son divertidas!

PHP tiene una TONELADA de funciones de matriz, por lo que hay muchas soluciones potenciales.

Se me ocurrió este como un desafío personal, que no utiliza bucles, filtros o mapas.

Esta solución utiliza array_intersect para encontrar valores que existen en ambas matrices, entonces valores_array junto con array_fill_keys para convertirlos en arreglos asociativos poblados con TRUE o FALSEy finalmente array_merge para ponerlos juntos en una sola matriz:

$array1 = array( 0 => "car1", 1 => "car2", 2 => "car3", 3 => "car4", 4 => "car5");
$array2 = array( 0 => "car1", 1 => "car4", 2 => "car5" );

// Find all values that exist in both arrays
$intersect = array_intersect( $array1, $array2 );
// Turn it into an associative array with TRUE values
$intersect = array_fill_keys( array_values($intersect), TRUE );
// Turn the original array into an associative array with FALSE values
$array1 = array_fill_keys( array_values( $array1 ), FALSE );

// Merge / combine the arrays - $intersect MUST be second so that TRUE values override FALSE values
$results = array_merge( $array1, $intersect );

var_dump( $results ); resultados en:

array (size=5)
  'car1' => boolean true
  'car2' => boolean false
  'car3' => boolean false
  'car4' => boolean true
  'car5' => boolean true

  • ¡Inteligente! array_fill_keys es una función que nunca he tenido que usar.

    –Paul Carlton

    24 de noviembre de 2016 a las 0:44

avatar de usuario
Pablo Carlton

array_map o array_combine en realidad no devuelve lo que quieres. Si quisieras usar array_map al efecto deseado sin escribir un bucle foreach, a continuación le da el resultado deseado. Tenga en cuenta que tiene que pasar array3 como una referencia.

<?php 

$array1 = array( 0 => "car1", 1 => "car2", 2 => "car3", 3 => "car4", 4 => "car5");
$array2 = array( 0 => "car1", 1 => "car4", 2 => "car5" );
$array3 = [];

array_map(function($a) use ($array2, &$array3) {
    $array3[$a] = in_array($a, array_values($array2));
}, $array1);

var_dump($array3);

Producción:

array(5) {
  ["car1"]=>
   bool(true)
  ["car2"]=>
   bool(false)
  ["car3"]=>
   bool(false)
  ["car4"]=>
   bool(true)
  ["car5"]=>
   bool(true)
}

Esto es lento, pero debería hacer lo que usted quiere y ser fácil de entender.

// Loop over the outer array which we're told has all the categories
$result = array();
foreach($array1 as $sCar1) {
  $found = false;

  // Loop over the categories of the post
  foreach($array2 as $sCar2) {

    // If the current post category matches
    // the current category we're searching for
    // note it and move on
    if($sCar2 == $sCar1) {
        $found = true;
        break;
    }
  }

  // Now indicate in the result if the post has the current category
  $result[$sCar1] = $found;
}

avatar de usuario
rrr_2010

<?php
//EXAMPLE 1

$array1 = [0 => "car1", 1 => "car2", 2 => "car3", 3 => "car4", 4 => "car5"];
$array2 = [0 => "car1", 1 => "car4", 2 => "car5"];
$resultArray = [];

foreach ($array1 as $key => $val) {
    $resultArray[$val] = in_array($val, $array2);
}

var_dump($resultArray);
?>

<?php
//EXAMPLE 2

$array1 = [0 => "car1", 1 => "car2", 2 => "car3", 3 => "car4", 4 => "car5"];
$array2 = [0 => "car1", 1 => "car4", 2 => "car5"];
$resultArray = [];

$flipped = array_flip($array2);

foreach ($array1 as $key => $val) {
    $resultArray[$val] = isset($flipped[$val]);
}


var_dump($resultArray);

?>

RESULTADO:

array (size=5)
  'car1' => boolean true
  'car2' => boolean false
  'car3' => boolean false
  'car4' => boolean true
  'car5' => boolean true

avatar de usuario
sevavietl

Con array_count_values Es tan simple como esto:

$results = array_map(function ($count) {
    return $count !== 1;
}, array_count_values(array_merge($array1, $array2)));

Básicamente, fusionamos dos matrices y luego contamos las ocurrencias de valores. Luego, si un conteo no es igual a 1, asignamos el valor a truey de lo contrario – false. Interesante, eso esto funcionará independientemente de qué matriz sea más corta.

Aquí está demostración de trabajo.

Sé consciente de array_count_values función lanza E_WARNING para cada elemento que no es una cadena o un entero. Entonces, este enfoque funcionará solo en matrices de cadenas y enteros.

Además, este enfoque podría fallar si los elementos de su matriz no son únicos, para esta situación debe aplicar array_unique a cada matriz de antemano.

¿Ha sido útil esta solución?