Question

I have two arrays and I need to find the difference between the two and display them in an unordered list.

I can loop through the master array for a single match but I have no clue how to loop through the master list for more than one key value and do it efficiently.

Below is an excerpt of key values from each array:

Master array to be searched

foreach ( $levels as $level ) {
  $output .= '<li>' . $level['name'] . '</li>';

The array that contains possible matches

foreach ( $login_member_levels as $level ) {
  $output .= '<li>' . $level_array[]=$level->level . '</li>';

Added info for multidimensional question...

Here are the two multidimensional arrays I need to compare but the sub-arrays do not not match up:

I need to compare in the first array [levels][level_id] and in the [levels][level][id]

Array
(
  [success] => 1
  [member] => Array
    (
      [0] => Array
        (
          [ID] => 2
          [UserInfo] => Array
              (
                 [ID] => 2
                 [caps] => Array
                      (
                          [administrator] => 1
                      )
              )
          [Sequential] => 
          [Levels] => Array
            (
                [1347037874] => stdClass Object
                    (
                       [Level_ID] => 1347037874
                       [Name] => HFM-Cardiac Resistance Training Program
                       [Cancelled] => 
                    )

                [1347037875] => stdClass Object
                   (
                       [Level_ID] => 1347037875
                       [Name] => HFM-Official Heart Health Guide
                       [Cancelled] => 
                       [1347037876] => stdClass Object
                       (
                             [Level_ID] => 1347037876
                             [Name] => HFM-All Access Cardiac Success Club
                         [Cancelled] => 
                            )
                    )
        )
    )   

Here is the second array:

Array
(
    [success] => 1
    [levels] => Array
        (
            [level] => Array
                (
                    [0] => Array
                        (
                            [id] => 1347037871
                            [name] => HFM-Ask the Experts
                            [_more_] => /levels/1347037871
                        )
                    [1] => Array
                        (
                            [id] => 1347037874
                            [name] => HFM-Cardiac Resistance Training Program
                            [_more_] => /levels/1347037874
                        )
                    [2] => Array
                        (
                            [id] => 1347037875
                            [name] => HFM-Official Heart Health Guide
                            [_more_] => /levels/1347037875
                        )
                    [3] => Array
                        (
                            [id] => 1347037876
                            [name] => HFM-All Access Cardiac Success Club
                            [_more_] => /levels/1347037876
                        )
                )
        )
   [supported_verbs] => Array
        (
           [0] => GET
           [1] => POST
        )
)
Was it helpful?

Solution

Note that the array_diff function, as Jod correctly suggested you, will compare array1 against array2 and returns the difference.
Example:

$array1 = array("green", "red", "blue", "red");
$array2 = array("green", "yellow", "brown");
$result = array_diff($array1, $array2);

var_dump($array1);
var_dump($array2);
var_dump($result);

will give you:

// Array1
array(4) {
  [0] => "green"
  [1] => "red"
  [2] => "blue"
  [3] => "red"
}

// Array2
array(3) {
  [0] => "green"
  [1] => "yellow"
  [2] => "brown"
}

// array_diff result
array(3) {
  [1] => "red"
  [2] => "blue"
  [3] => "red"
}

because those are values present in array1 but NOT in array2·

If you are interested in getting an array containing ALL the differences (as values) between two (or multiple) arrays, I wrote a function for that:

function array_diff_all()
{
    $arguments = func_get_args();

    $merged         = array();    
    $intersected    = $arguments[0];
    for ($i = 0; $i < count($arguments); $i++)
    {
        $merged         = array_merge($merged, $arguments[$i]);
        $intersected    = array_intersect($intersected, $arguments[$i]);
    }

    return array_values(array_filter( array_unique(array_diff($merged, $intersected)) ));
}

Example of usage: (same as before)

$array1 = array("green", "red", "blue", "red");
$array2 = array("green", "yellow", "brown");
$result = array_diff_all($array1, $array2);

var_dump($array1);
var_dump($array2);
var_dump($result);

will give you

// Array1
array(4) {
  [0] => "green"
  [1] => "red"
  [2] => "blue"
  [3] => "red"
}

// Array2
array(3) {
  [0] => "green"
  [1] => "yellow"
  [2] => "brown"
}

// array_diff_all result
array(4) {
  [0] => "red"
  [1] => "blue"
  [2] => "yellow"
  [3] => "brown"
}

Please note:
1) It's working well only with indexed arrays, if you use hash (associative arrays) it's working well only if the keys are uniques.
2) The resulting array is reindexed, this means that a value can have a different index compared to its original.
3) Duplicate values are removed and a unique resulting array is returned.
4) You can compare multiple arrays at once.
Example:

$first  = array('foo', 'moo', 'zoo');
$second = array('foo', 'done', 'gone');
$third  = array('foo', 'mix', 'zoo');

var_dump( array_diff_all($first, $second, $third) );

will output:

array(5) {
  [0] => "moo"
  [1] => "zoo"
  [2] => "done"
  [3] => "gone"
  [4] => "mix"
}

EDIT:
For the second part of your question:
You cannot use the mentioned approach for your specific case, because you have two arrays completely different to compare, moreover the first one contains objects.
To solve your issue you need to:
A) understand how to access the 'levels' array of the first array. It looks to me that you have to iterate over $array1['member'], each of them has a 'levels' array, I guess.
It can be something like:

foreach ($array1['member'] as $member)
{
    $levels = $member['levels'];
    ...
}

At this point $levels should be an object array like:

[Levels] => Array
    (
        [1347037874] => stdClass Object
            (
        [Level_ID] => 1347037874
        [Name] => HFM-Cardiac Resistance Training Program
        [Cancelled] => 
    )

    [1347037875] => stdClass Object
    (
                [Level_ID] => 1347037875
        [Name] => HFM-Official Heart Health Guide
        [Cancelled] => 
            )

    [1347037876] => stdClass Object
    (
        [Level_ID] => 1347037876
            [Name] => HFM-All Access Cardiac Success Club
        [Cancelled] => 
            )
    )

B) The idea is to note that the level_id you need to compare is the key of this 'levels' array, while the array2 is a 'normal' multidimensional array (I mean not containing object) .. so we can safely use built-in array functions of php over it.
We can assume that the level_id is complicated enough to be unique inside $array2, so we can only check if a certain level_id is present inside (recursively) the $array2 as a value, without caring of comparing the 'id' key in it.

To do that you need:
C) a recursive in_array function I wrote:

function in_array_recursive($needle, $haystack)
{ 

    $it = new RecursiveIteratorIterator(new RecursiveArrayIterator($haystack)); 

    foreach ($it AS $element)
        if ($element === $needle)
            return true; 

    return false; 
}


D) create an helper to be used as callback function of array_filter

function array_diff_helper($var)
{
    global $array2;
    return !(in_array_recursive(trim($var), $array2));
}

Please note use the name of your second array here if different.
E) Finally you can get the differences of level_ids:

$diff = array_filter(array_keys($levels), "array_diff_helper");



So .. the loop you need might be something as easy as:

foreach ($array1['member'] as $member)
{
    $not_matching_ids = array_filter(array_keys($member['levels']), "array_diff_helper");
}

Hope this helps, cheers! :)

OTHER TIPS

Use array_diff() to generate an array of non matching values.

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

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top