【问题标题】:php compare multidimensional array and extract overlapping valuesphp比较多维数组并提取重叠值
【发布时间】:2011-06-20 10:53:25
【问题描述】:

我从事一些单元测试。我的结果是大的多维数组。我不想比较整个数组,而只想比较这个“分层结构”中的几个键。这是我预期的数组的 sn-p:

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

结果数组更大,但有些条目与我预期的相同。所以我想比较它们。如果值相等。

我尝试了一些 array_intersect、diff 函数,但它们似乎不适用于多维数组。

有没有一种方法可以在我预期的数组上使用 array_walk_recursive 并获得结果数组的适当键?指针或引用之类的东西?

【问题讨论】:

  • “我的结果是大的多维数组”——在 PHP 中没有多维数组这样的东西!它们是分层的
  • 是的,分层是更好的术语。

标签: php arrays multidimensional-array comparison


【解决方案1】:

array_intersect() 不比较关联键,它只查看值,您需要使用array_intersect_assoc() 比较键和值。然而,这个函数只会比较基键而不是嵌套数组的键。

 array_intersect_assoc($expected, $result);

也许最好的解决方案是使用array_uintersect_assoc() 使用以下技术,您可以在其中定义比较函数。

$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>';

除了您的 cmets,以下代码应返回 $result 中的所有元素,这些元素具有 $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;
}

【讨论】:

  • 我想要一个与预期类似的数组,但值应该来自具有相似结构的结果数组。 $expected sn-p 是结果的一部分,还有更多带有额外嵌套的键,但这对结果无关紧要。我想避免类似 assert(7895, $result['gordon']['agrar']['sum']
  • 看来array_uintersect_assoc只适用于第一级。
  • 嗯....我需要类似array_merge的东西,但合并后的结构应该具有预期的结构,但具有结果的值。
  • 它比较两个基本数组的键(预期和结果),如果键相等,它将比较每个数组中位置 [key] 处的值的序列化形式。我误解了你的目标吗?如果是这样,请澄清。
  • 所以你想确认结构是一样的,如果是,那么包括在输出中?
【解决方案2】:

我知道应该有办法解决这个问题!它的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);

这就是解决方案!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-02
    • 1970-01-01
    • 2020-03-07
    • 1970-01-01
    • 2011-11-15
    相关资源
    最近更新 更多