2

I have two two-dimensional arrays I'd liked to compare to one another:

$array1
Array
(
    [0] => Array
        (
            [A] => GB
            [B] => Harry
            [C] => British Army
            [D] => Eton College
            [E] => Cressida Bonas
        )

    [1] => Array
        (
            [A] => GB
            [B] => William
            [C] => Royal Air Force
            [D] => Eton College
            [E] => Catherine Middleton
        )

)

$array2
Array
(
    [0] => Array
        (
            [A] => GB
            [B] => Harry
            [C] => British Army
            [D] => Eton College
            [E] => Cressida Bonas
        )

    [1] => Array
        (
            [A] => GB
            [B] => James
            [C] => British Army
            [D] => Millfield
            [E] => Unknown
        )

)

And produce a boolean true/false results array as follows if any of the child array values differ:

$results_array
Array
(
    [0] => Array
        (
            [0] => true
        )

    [1] => Array
        (
            [0] => false      
        )

)

UPDATE: Both arrays will always have the same length parent arrays (but the child arrays values may vary in length).

I can't wrap my head around how to use foreach in a recursive manner to get the results array.

Any general ideas or advice?

Elijah Paul
  • 281
  • 4
  • 22
  • What data would you like the results array to contain? Correct me if I'm wrong - you want the results array to contain a subarray of duplicate values and another with different values? – Joshua Kissoon Mar 02 '14 at 09:48
  • 3
    Dump the two arrays using `var_export` and update your question. – Shankar Narayana Damodaran Mar 02 '14 at 09:53
  • @JoshuaKissoon I'd like the results array to contain a boolean true or false data type depending on whether any of sub arrays are duplicates or not. e.g true for duplicates, and false for different. Will update the question to make this clearer. – Elijah Paul Mar 02 '14 at 10:02
  • @ShankarDamodaran Excuse my ignorance (still very new to arrays and foreach), but why would I dump the arrays with var_export? How does this help? – Elijah Paul Mar 02 '14 at 10:04
  • @ElijahPaul Does it matter the order of items? or once a set of items is in both arrays it's duplicate? – Joshua Kissoon Mar 02 '14 at 10:10
  • @JoshuaKissoon No the order doesn't matter for the child array values. Actually the child arrays are generated by another script, so if they're duplicates the order will always be the same. – Elijah Paul Mar 02 '14 at 10:18
  • I don't understand why you need a single element array with a boolean; why not just `[0 => true, 0 => false]` as output? – Ja͢ck Mar 02 '14 at 10:21
  • @ElijahPaul Check I have posted an answer that will work to check if values are duplicated – Joshua Kissoon Mar 02 '14 at 10:23
  • @Jack That's a good question. I have to merge the results array with another two-dimensional array once it's generated. Would I not get an 'off' result if it's a single element array, or then have to convert it? Correct me if I'm wrong? Am still new to this. – Elijah Paul Mar 02 '14 at 10:24
  • @ElijahPaul, I mentioned `var_export` format because that will make easier for us to work with the arrays. – Shankar Narayana Damodaran Mar 02 '14 at 10:35
  • 3
    @ShankarDamodaran Just tried `var_export`. I see what you mean. Thanks for the tip. – Elijah Paul Mar 02 '14 at 10:47
  • Have you tried my answer, btw? :) – Ja͢ck Mar 02 '14 at 10:53

4 Answers4

0

I don't know what you are trying to do with a foreach loop. Are you saying every array will have 2 child arrays or every child array will have 5 values? Regardless, I hope this helps you!

I would use some of these:

  • array_intersect
  • array_intersect_assoc
  • array_diff
  • array_diff_assoc

Code:

<?php

$array1 = [
    [
        'A' => 'GB',
        'B' => 'Harry',
        'C' => 'British Army',
        'D' => 'Eton College',
        'E' => 'Cressida Bonas',
    ],
    [
        'A' => 'GB',
        'B' => 'William',
        'C' => 'Royal Air Force',
        'D' => 'Eton College',
        'E' => 'Catherine Middleton',
    ]
];

// What Values are in common
$result1 = array_intersect_assoc($array1[0], $array1[1]);
print_r($result1);

$array2 = [
    [
        'A' => 'GB',
        'B' => 'Harry',
        'C' => 'British Army',
        'D' => 'Eton College',
        'E' => 'Cressida Bonas',
    ],
    [
        'A' => 'GB',
        'B' => 'James',
        'C' => 'British Army',
        'D' => 'Millfield',
        'E' => 'Unknown',
    ]
];

// What values are different
$result2 = array_diff_assoc($array2[0], $array2[1]);
print_r($result2);


// A Way to check numerically
$perfectMatch = 5;
$intersect = array_intersect_assoc($array1[0], $array1[1]);
$intersectCount = count($intersect);
if ($intersectCount != $perfectMatch) {
    echo "<br> Not Every value matches.";
} else {
    echo "<br> Perfect Match!";
}

To compare the full arrays $array1 and $array2 you can do:

<?php 

// (With array code above)

$c1 = count($array1);
$c2 = count($array2);
if ($c1 != $c2) {
    echo "<br>Array Children must be the same";
}

$result = [];
for ($i = 0; $i < $c1; $i++) {
    $in_common = array_intersect($array1[$i], $array2[$i]);
    $result[] = count($intersect);
}

print_r($result);
JREAM
  • 5,741
  • 11
  • 46
  • 84
  • Will clarify my question. The child arrays may vary, but the parent arrays will always be constant. – Elijah Paul Mar 02 '14 at 10:13
  • Thanks, added a way to compare the groups. In that case you wouldn't need to verify the array children count :) – JREAM Mar 02 '14 at 10:14
0

You could do using == operator. Passing the first array as key-array ($k=>$arr) [since the value is another array]. Now compare the two arrays using the simple == comparison operator. You can even perform strict matching using the === operator.

<?php
$arr1=array(0=>array('A'=>'GB','B'=>'Harry','C'=>'British Army'),1=>array('A'=>'GB','B'=>'William','C'=>'Royal Air Force'));
$arr2=array(0=>array('A'=>'GB','B'=>'Harry','C'=>'British Army'),1=>array('A'=>'GB','B'=>'James','C'=>'British Army'));

foreach($arr1 as $k=>$arr)
{
    $resarr[][$k]=($arr==$arr2[$k])? "true" : "false";
}
print_r($resarr);

Demo

OUTPUT :

Array
(
    [0] => Array
        (
            [0] => true
        )

    [1] => Array
        (
            [1] => false
        )

)
Shankar Narayana Damodaran
  • 68,075
  • 43
  • 96
  • 126
0

You can just use array_map(), assuming both arrays are of the same length:

$result = array_map(function($a, $b) {
    return [$a == $b]; // create single element boolean array
}, $array1, $array2);

You can use either == or ===; the former (==) will yield true if both arrays have the same key and value pairs, whereas the latter (===) will only yield true if the keys of both arrays are also in the same order.

Ja͢ck
  • 170,779
  • 38
  • 263
  • 309
0

Some answers use the == operator; however that will not work if the arrays do not have the same key=>value matchings; Try this:

$results = array();
foreach ($array1 as $i => $subarray)
{
    /* No need to proceed if subarray[i] does not exist in the second array */
    if(!is_array($array2[$i]))
    {
        $results[$i] = false;
        continue;
    }        
    $results[$i] = (count(array_diff($array1[$i], $array2[$i])) == 0) ? true : false;
}

This solution is a bit slower than using the == comparison operator. However using the == will not work for a case like:

$array1 => array(1 => "John", 2 => "James");
$array2 => array(1 => "James", 2 => "John");

Here, the keys are not the same, but the values are duplicated. Solutions using == will return false when comparing these arrays.

$array1 == $array2     // False
Joshua Kissoon
  • 3,269
  • 6
  • 32
  • 58
  • This solution is definitely an overkill. a `count` , an `is_array()` check and an `array_diff`. These are not at all required , you are just complicating the solution. – Shankar Narayana Damodaran Mar 02 '14 at 10:31
  • It does in fact have some extra overhead, but works for all cases. If you can find a better/faster solution including solving the case where keys are not in the same order even if there is a duplicate array, please post it. This is all I came up with. – Joshua Kissoon Mar 02 '14 at 10:35