开发者

php compare multidimensional array and extract overlapping values

开发者 https://www.devze.com 2023-03-13 22:32 出处:网络
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

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 se开发者_如何学编程ems 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?


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


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!

0

精彩评论

暂无评论...
验证码 换一张
取 消