【问题标题】:Create a 'results' array based on comparison of two two-dimensional arrays?根据两个二维数组的比较创建一个“结果”数组?
【发布时间】:2014-04-03 06:35:11
【问题描述】:

我有两个想要相互比较的二维数组:

$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
        )

)

如果任何子数组值不同,则生成一个布尔真/假结果数组,如下所示:

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

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

)

更新: 两个数组将始终具有相同长度的父数组(但子数组值的长度可能不同)。

我不知道如何以递归方式使用foreach 来获取结果数组。

有什么一般性的想法或建议吗?

【问题讨论】:

  • 您希望结果数组包含哪些数据?如果我错了,请纠正我 - 您希望结果数组包含一个重复值的子数组和另一个具有不同值的子数组?
  • 使用var_export 转储两个数组并更新您的问题。
  • @JoshuaKissoon 我希望结果数组包含布尔真或假数据类型,具体取决于任何子数组是否重复。例如,对于重复项为 true,对于不同项为 false。将更新问题以使这一点更清楚。
  • @ShankarDamodaran 请原谅我的无知(对数组和 foreach 还是很陌生),但我为什么要用 var_export 转储数组呢?这有什么帮助?
  • @ShankarDamodaran 刚试过var_export。我明白你的意思了。感谢您的提示。

标签: php arrays foreach associative-array array-difference


【解决方案1】:

您可以使用== 运算符。将第一个数组作为键数组 ($k=>$arr) [因为值是另一个数组]。现在使用简单的== 比较运算符比较两个数组。您甚至可以使用=== 运算符执行严格匹配。

<?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
        )

)

【讨论】:

  • 马上试试这个。看起来像是我试图在脑海中制定的内容,但无法完全理解。
  • 如果密钥不同,这将不起作用。例如,如果您有 array1(1=>"Harry", 2=>"Paul") 和 array2(1=>"Paul", 2=>"Harry");这个答案将返回 false,即使这些数组彼此重复
  • @JoshuaKissoon,你没看到我提到了=== 运算符作为替代吗??? 评论前请正确阅读答案。
  • 是的,我看到了,我只是指出一种情况,这不起作用。
  • @ShankarDamodaran 效果很好。也很简单。非常感谢。
【解决方案2】:

我不知道你想用foreach 循环做什么。你是说每个数组都有2 child arrays 还是每个子数组都有5 values?无论如何,我希望这对你有帮助!

我会使用其中的一些:

  • array_intersect
  • array_intersect_assoc
  • array_diff
  • array_diff_assoc

代码:

<?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!";
}

要比较完整的数组 $array1$array2,您可以这样做:

<?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);

【讨论】:

  • 会澄清我的问题。子数组可能会有所不同,但父数组将始终保持不变。
  • 谢谢,添加了一种比较组的方法。在这种情况下,您不需要验证数组子项计数:)
【解决方案3】:

您可以只使用array_map(),假设两个数组的长度相同:

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

您可以使用=====;如果两个数组具有相同的键和值对,则前者 (==) 将产生 true,而如果两个数组的键的顺序也相同,则后者 (===) 只会产生 true

【讨论】:

    【解决方案4】:

    有些答案使用 == 运算符;但是,如果数组没有相同的 key=>value 匹配,这将不起作用;试试这个:

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

    此解决方案比使用 == 比较运算符要慢一些。但是,使用 == 不适用于以下情况:

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

    这里的键不一样,但是值是重复的。比较这些数组时,使用 == 的解决方案将返回 false。

    $array1 == $array2     // False
    

    【讨论】:

    • 这个解决方案绝对是矫枉过正。一个 count ,一个 is_array() 支票和一个 array_diff。这些根本不是必需的,您只是使解决方案复杂化。
    • 它确实有一些额外的开销,但适用于所有情况。如果您能找到更好/更快的解决方案,包括解决即使存在重复数组的键顺序不同的情况,请发布。这就是我想出的全部。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-05
    • 2011-05-28
    相关资源
    最近更新 更多