【问题标题】:Comparing Two Arrays for Two Values比较两个数组的两个值
【发布时间】:2015-06-12 18:41:27
【问题描述】:

我正在努力使用适当的逻辑来比较以下数组:

$a = [
    "ip" => [
        "1.2.3.4",
        "4.3.2.1",
    ],
    "domain" => [
        "example.com",
        "another.domain",
    ],

];

$b = [
    [
        "id"=> 136589,
        "metaname" => "ip",
        "metavalue" => "1.2.3.4",
    ],
    [
        "id"=> 136590,
        "metaname" => "domain",
        "metavalue" => "example.com",
    ],
];

我需要遍历$a 以找到$b 中不存在的键('ip') 值('1.2.3.4') 组合。在数组$a中,我需要捕获ip'4.3.2.1'和域'another.domain'

$b 有可能具有不同键的匹配值吗?

一个很好的例子是'ip' 地址。可能的与 IP 相关的元名称值为 'ip''ip.dst''ip.src'。回到示例数据 - 即使'ip' 匹配,如果元名称不匹配,也应该跳过它。

foreach ($a as $metaName => $metaValues)
{
    foreach ($metaValues as $metaValue)
    {
        foreach ($b as $row)
        {
            if (in_array($metaName, $row) && in_array($metaValue, $row))
            {
                # this pair exists, move on to next $metaName-$metaValue pair
                break;
            }
            # this is where i am now, making small progress
            # more trial and error going on
        }
    }
}

在我的示例代码中,注释是我需要帮助的地方。我尝试了不同检查和循环的各种迭代来捕获适当的数据,但无济于事......

  • in_array($metaValue, $row)
  • array_keys($row, $metaValue)

结合各种if 语句等等,但这无济于事。

如果我的描述不清楚,也许下表会有所帮助。

+ A ---------------------+----+ B ------------------+ Comment ------------------------+
| ip, 1.2.3.4            | == | ip, 1.2.3.4         | Skip, no more checks            |
+------------------------+----+---------------------+---------------------------------+
| ip, 4.3.2.1            | != | ip, 1.2.3.4         | Keep checking                   |
|                        | != | domain, example.com | No more B to compare, I want A! |
+------------------------+----+---------------------+---------------------------------+
| domain, example.com    | != | ip, 1.2.3.4         | Keep checking                   |
|                        | == | domain, example.com | Skip, no more checks            |
+------------------------+----+---------------------+---------------------------------+
| domain, another.domain | != | ip, 1.2.3.4         | Keep checking                   |
|                        | != | domain, example.com | No more B to compare, I want A! | 
+------------------------+----+---------------------+---------------------------------+

【问题讨论】:

    标签: php arrays multidimensional-array


    【解决方案1】:

    只需稍作修改并使用reference,您就非常接近了。但是要小心第一个 foreach,第一个参数是 $metaname,但第二个还不是 $metavalue,你需要第二个 foreach 来循环它们:

    foreach ($a as $metaname => &$group) { // & is present to unset the original array
        foreach ($group as $i => $metavalue) { // here you get the distinct metavalues
            foreach ($b as $row) {
                if (!($row['metaname'] === $metaname)) {
                    continue;
                }
                if ($row['metavalue'] === $metavalue) {
                    unset($group[$i]);
                }
            }
        }
    }
    
    var_dump($a);
    

    之后是$a 中的var_dump()

    array(2) {
      ["ip"]=>
      array(1) {
        [1]=>
        string(7) "4.3.2.1"
      }
      ["domain"]=>
      &array(1) {
        [1]=>
        string(14) "another.domain"
      }
    }
    

    第一个 foreach() 将访问 $a 数组的不同值,而 $metavalue 实际上是包含这些元值的 数组

    【讨论】:

    • 啊哈!即使我的只是部分工作,这也比我拥有的完整代码要好得多。非常感谢。
    猜你喜欢
    • 2023-03-26
    • 1970-01-01
    • 1970-01-01
    • 2019-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多