2016-02-23 58 views
2

我有一个从JSON结构转换而来的大数组,其中包含未知数量的元素和子元素。递归遍历PHP多维数组进行比较

喜欢的东西:

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

因此,在结束我会存储这是在$索引上市的别名下的$马尔找到的所有值的基本数组。就像这样:

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

这已经两天头疼,现在我似乎无法弄清楚要经过这一点的最好办法。我试图走过$ indexer达到它的结尾,获得“变量名”,然后与$ marr比较来存储它的数据,但我总是似乎失去了$ indexer的父节点,同时试图以递归方式执行此操作。我会很感激任何建议。

+0

你怎么' “variable_name_1”'两?这些名字很重要吗? – Kalkran

+0

不确定,为什么你需要一个递归函数..只需创建一个嵌套循环 – Philipp

+0

@Kalkran这些名称在$ indexer中,它们在理论上是需要的,因为我想从JSON Web服务中存储数据以用于一堆SQL查询。他们仅仅是这里的例子,在理论上我可以说,其中有20个用于五个不同的查询。但对于我正在尝试构建的应用程序而言,这是一个不同的逻辑步骤,我想这里与此无关。 – Ivo

回答

1

您可以使用此递归函数:

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

随着例子给出的数据,$店将是:

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

耶稣,它的简单完美!非常感谢。 – Ivo

+0

你是最受欢迎的。 – trincot

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 
) 
+0

这不是一个糟糕的解决方案,我不知道那些递归迭代器类,谢谢。 – Ivo