2016-02-23 60 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