Stack Overflow is a community of 4.7 million programmers, just like you, helping each other.

Join them; it only takes a minute:

Sign up
Join the Stack Overflow community to:
  1. Ask programming questions
  2. Answer and help your peers
  3. Get recognized for your expertise

I work on some unit-tests. My results are big multidimensional arrays. I don't want to compare the whole array, but only a few keys in this "hierachical structure". Here is a snippet of my expected array:

    $expected = array(
        'john' => array(
            'maham' => 4563,
        ),
        'gordon' => array(
            'agrar' => array(
                'sum' => 7895,
            ),
        ),
        'invented' => 323,
    );

The result array is bigger but there are some entries which are the same as in my expected one. So I want to compare them. If the values are equal.

I tried some array_intersect, diff functions but It seems that they not work on an multidimensionals array.

Is there a maybe a way to use array_walk_recursive on my expected array and get the appropriate key of the result array? Something like a pointer or a reference?

share|improve this question
    
"My results are big multidimensional arrays" - no such thing as multidimensional arrays in PHP! They are hierarchical – symcbean Jun 20 '11 at 11:58
    
yes, hierachical is the better term for that. – GeisterKampf Jun 20 '11 at 12:19

array_intersect() does not compare associative keys, it only looks at the values, you will need to use array_intersect_assoc() to compare both key and value. However this function will only compare the base key not the keys of the nested arrays.

 array_intersect_assoc($expected, $result);

Perhaps the best solution is to use the following technique using array_uintersect_assoc(), where you can define the compare function.

$intersect = array_uintersect_assoc($expected, $result, "comp"));

function comp($value1, $value2) {
  if (serialize($value1) == serialize($value2)) return 0;
  else return -1;
}

echo '<pre>';
print_r($intersect);
echo '</pre>';

Further to your comments, the following code should return all elements in $result which have the expected structure set out in $expected.

// get intersecting sections
$intersect = array_uintersect_assoc($expected, $results, "isStructureTheSame");
//print intersecting set
echo "<pre>";
print_r($intersect);
echo "</pre>";
//print results that are in intersecting set (e.g. structure of $expected, value of $results
echo "<pre>";
print_r(array_uintersect_assoc($results, $intersect, "isStructureTheSame"));
echo "</pre>";

function isStructureTheSame($x, $y) {
    if (!is_array($x) && !is_array($y)) {
        return 0;
    }
    if (is_array($x) && is_array($y)) {
        if (count($x) == count($y)) {
            foreach ($x as $key => $value) {
                if(array_key_exists($key,$y)) {
                    $x = isStructureTheSame($value, $y[$key]);
                    if ($x != 0) return -1;
                } else {
                    return -1;
                }
            }
        }
    } else {
        return -1;
    }
    return 0;
}
share|improve this answer
    
I want an array which is like the expected one, but the values should be from the result array which has a similar structure. The $expected snippet is part of the result, there more keys with additional nesting but this doesn't matter for the result. I want to avoid something like assert(7895, $result['gordon']['agrar']['sum'] – GeisterKampf Jun 20 '11 at 12:07
    
It seems array_uintersect_assoc only works on the first level. – GeisterKampf Jun 20 '11 at 12:13
    
Hm.... I need something like array_merge but the merged one should have the structure of the expected but the values of the result. – GeisterKampf Jun 20 '11 at 12:16
    
It compares the keys of both base arrays (expected and result), if the keys are equal it will then compare the serialised form of the value held in each array at position [key]. Am I misunderstanding your objective? If so, please clarify. – GordyD Jun 20 '11 at 12:18
    
So you want to confirm that the structure is the same, and if so then include in the output? – GordyD Jun 20 '11 at 12:21

I knew there should be a method to solve this! Its array_replace_recursive!

$expected = array_replace_recursive($result, array(
    /* expected results (no the whole array) */
));

// $expected is now exactly like $result, but $values differ.
// Now can compare them!
$this->assertEquals($expected, $result);

This is the solution!

share|improve this answer
    
+1 For answering own question – trejder Sep 23 '13 at 6:44

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.