Home » Php » php – How to return array with true/false values comparing 2 arrays?

php – How to return array with true/false values comparing 2 arrays?

Posted by: admin July 12, 2020 Leave a comment

Questions:

I am trying to generate array as a result of comparison 2 arrays: 1st array has more elements such as:

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

and 2nd array has not all elements:

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

So there are all possible categories (array1) and categories assigned to post (array2) (it’s a WordPress thing).
I am trying to compare that arrays (but not with array_diff() function which gave me elements values instead boolean) and get result as true/false. So I want to compare each values of arrays and generate array map or maybe using array_combine() function to get array like that:

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

etc…
It is important to output array have all categories and their results (true, false) for post.
Is there any simple way to do it or maybe is it function which I could use?

How to&Answers:

Arrays are fun!

PHP has a TON of array functions, and so there’s lots of potential solutions.

I came up with this one as a personal challenge, which uses no loops, filters, or maps.

This solution uses array_intersect to find values that exist in both arrays, then array_values along with array_fill_keys to turn them into associative arrays populated with TRUE or FALSE, and finally array_merge to put them together into a single array:

$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 ); results in:

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

Answer:

array_map or array_combine does not actually return what you want. If you wanted to use array_map to the desired effect without writing a foreach loop, below gives you the desired result. Note you have to pass array3 as a reference.

<?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);

Output:

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

Answer:

This is slow, but it should do what you want, and be easy to understand.

// 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;
}

Answer:

<?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);

?>

RESULT:

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

Answer:

With array_count_values it is as simple as this:

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

So basically, we merge two arrays together, then count occurrences of values. Then if a count is not equal to 1 we map value to true, and otherwise – false. Interesting, that this will work regardless of which array is shorter.

Here is working demo.

Be aware, that array_count_values function throws E_WARNING for every element which is not string or integer. So this approach will work only on arrays of strings and integers.

Also, this approach might fail if your array elements not unique, for this situation you have to apply array_unique to each array beforehand.