dpp66953
2016-02-23 12:27
浏览 128
已采纳

递归遍历PHP多维数组进行比较

I have a large array converted from a JSON structure with an unknown number of elements and sublevels.

Something like:

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

And on the other hand, I have an array of items I need to compare and find out if they are in the array above. This "indexer" will always mirror the same structure above (it's generated before the comparison step) because I thought that would help me ensure a proper comparison in an easier way.

Something like:

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

I'm not entirely sure how best to compare these. I have looked into array_walk_recursive() which only returns the leaf values and I have tried to write my own attempts at a basic recursive function that would perform a foreach() which would then try to do something like:

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

So that at the end I would have a basic array that stored all values found on $marr under an alias that was listed on $indexer. Like this:

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

This has been a headache for two days now and I can't seem to figure out the best way to go through this. I'm trying to walk through $indexer to reach its ending, obtain the "variable name", and then compare with $marr to store its data, but I always seem to lose the parent nodes of $indexer while trying to do this recursively. I would appreciate any advice at all.

  • 写回答
  • 好问题 提建议
  • 关注问题
  • 收藏
  • 邀请回答

2条回答 默认 最新

  • dor65412 2016-02-23 12:39
    已采纳

    You could use this recursive function:

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

    And then call it like this:

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

    With the example data given, $store will be:

    array (
      'variable_name_1' => '2014-12-31',
      'variable_name_2' => '2015-01-02',
    )
    
    已采纳该答案
    评论
    解决 无用
    打赏 举报
  • ds342222 2016-02-23 12:48

    Here I would like to suggest do not maintain indexer, you can use iterator and create new array using associated keys.

    For example have a look on below solution:

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

    Output:

    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
    )
    
    评论
    解决 无用
    打赏 举报

相关推荐 更多相似问题