【问题标题】:Recursive walking through a PHP multidimensional array to make a comparison递归遍历 PHP 多维数组以进行比较
【发布时间】:2016-06-05 07:00:40
【问题描述】:

我有一个从 JSON 结构转换而来的大型数组,其中包含未知数量的元素和子级别。

类似:

$marr = array
(
    "Order" => array
    (
        "Details" => array
        (
            "Document" => array
            (
                "Number" => "1585636772",
                "Date" => "2014-12-31"
            ),
            "Delivery" => array
            (
                "Date" => "2015-01-02",
                "TrackingCode" => "5703",
                "Name" => "Example Name",
                "Address" => "Example Address"
            )
        )
    )
);

另一方面,我有一组项目需要比较并找出它们是否在上面的数组中。这个“索引器”将始终反映上述相同的结构(它是在比较步骤之前生成的),因为我认为这将帮助我以更简单的方式确保正确的比较。

类似:

$indexer = array
(
    "Order" => array
    (
        "Details" => array
        (
            "Document" => array
            (
                "Date" => "variable_name_1"
            ),
            "Delivery" => array
            (
                "Date" => "variable_name_2"
            )
        )
    )
);

我不完全确定如何最好地比较这些。我研究了 array_walk_recursive() ,它只返回叶值,我试图编写我自己的尝试来编写一个基本的递归函数,该函数将执行一个 foreach() 这将然后尝试做类似的事情:

if( isset($marr["Order"]["Details"]["Document"]["Date"]) )
{
    $store[ $indexer["Order"]["Details"]["Document"]["Date"] ] = $marr["Order"]["Details"]["Document"]["Date"];
}

因此,最后我将拥有一个基本数组,该数组将在 $marr 上找到的所有值存储在 $indexer 上列出的别名下。像这样:

$store["variable_name_1"] = "2014-12-31";
$store["variable_name_2"] = "2015-01-02";

这两天一直很头疼,我似乎无法找出解决这个问题的最佳方法。我正在尝试遍历 $indexer 以达到其结尾,获取“变量名”,然后与 $marr 进行比较以存储其数据,但是在尝试递归执行此操作时,我似乎总是丢失了 $indexer 的父节点.如果有任何建议,我将不胜感激。

【问题讨论】:

  • 你如何得到"variable_name_1" 和两个?这些名字重要吗?
  • 不确定,为什么需要递归函数.. 只需创建一个嵌套循环
  • @Kalkran 这些名称在 $indexer 中,理论上它们是必需的,因为我想存储来自 JSON Web 服务的数据以在一堆 SQL 查询中使用。它们只是这里的示例名称,理论上我可以有,说,其中的 20 个用于五个不同的查询。但我想,对于我正在尝试构建的应用程序来说,这是一个不同的逻辑步骤,在这里不相关。
  • @Philipp 我不认为基本的嵌套循环可以在这里工作?

标签: php arrays recursion multidimensional-array


【解决方案1】:

在这里我建议不要维护索引器,您可以使用迭代器并使用关联键创建新数组。

例如看看下面的解决方案:

$array = array
(
    "Order" => array
    (
        "Details" => array
        (
            "Document" => array
            (
                "Number" => "1585636772",
                "Date" => "2014-12-31"
            ),
            "Delivery" => array
            (
                "Date" => "2015-01-02",
                "TrackingCode" => "5703",
                "Name" => "Example Name",
                "Address" => "Example Address"
            )
        )
    )
);


$new_array = array();
$iterator = new RecursiveIteratorIterator(new RecursiveArrayIterator($array));

foreach ($iterator as $key => $value) {
    $keys = array();
    $keys[] = $key;
    for ($i = $iterator->getDepth() - 1; $i >= 0; $i--) {
        $keys[] = $iterator->getSubIterator($i)->key();
    }
    $key_paths = array_reverse($keys);
    $new_array[implode('_', $key_paths)] = $value;
}

print_r($array);
print_r($new_array);

输出:

Array
(
    [Order] => Array
        (
            [Details] => Array
                (
                    [Document] => Array
                        (
                            [Number] => 1585636772
                            [Date] => 2014-12-31
                        )

                    [Delivery] => Array
                        (
                            [Date] => 2015-01-02
                            [TrackingCode] => 5703
                            [Name] => Example Name
                            [Address] => Example Address
                        )

                )

        )

)
Array
(
    [Order_Details_Document_Number] => 1585636772
    [Order_Details_Document_Date] => 2014-12-31
    [Order_Details_Delivery_Date] => 2015-01-02
    [Order_Details_Delivery_TrackingCode] => 5703
    [Order_Details_Delivery_Name] => Example Name
    [Order_Details_Delivery_Address] => Example Address
)

【讨论】:

  • 这不是一个糟糕的解决方案,我不知道那些递归迭代器类,谢谢。
【解决方案2】:

你可以使用这个递归函数:

function storeFromIndex($marr, $indexer) {
    if (!is_array($indexer)) {
        return array($indexer => $marr);
    }
    $store = [];
    foreach($indexer as $key => $subindexer) {
        $store = array_merge($store, storeFromIndex($marr[$key], $subindexer));
    }
    return $store;
}

然后这样称呼它:

$store = storeFromIndex($marr, $indexer);

根据给出的示例数据,$store 将是:

array (
  'variable_name_1' => '2014-12-31',
  'variable_name_2' => '2015-01-02',
)

【讨论】:

  • 天哪,它的简单性是完美的!非常感谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-01-18
  • 2019-08-15
  • 2012-07-17
  • 2012-11-06
  • 2017-10-09
  • 1970-01-01
  • 2020-09-06
相关资源
最近更新 更多