2015-05-13 16 views
2

我有一個從DB從單一的表如下輸出信息的數組:重建規則的陣列,以多維數組

Array 
(
    [0] => stdClass Object 
     (
      [users_info_id] => 1 
      [user_id] => 374 
      [user_email] => [email protected] 
      [address_type] => BT 
      [firstname] => Foo 
      [lastname] => Faa 
      [vat_number] => 
      [country_code] => US 
      [address] => Jajajaja 
      [city] => KOKOKOKOKOKO 
      [state_code] => MD 
      [zipcode] => 20745 
      [phone] => 2401111111 
     ) 
    [1] => stdClass Object 
     (
      [users_info_id] => 1 
      [user_id] => 374 
      [user_email] => [email protected] 
      [address_type] => ST 
      [firstname] => Foos 
      [lastname] => Faas 
      [vat_number] => 
      [country_code] => US 
      [address] => JSUSUSUS 
      [city] => LASOSLSL 
      [state_code] => DC 
      [zipcode] => 1234 
      [phone] => 1234567895 
     ) 
     // ... about 500 records... 
) 

什麼我要找的是重新構建陣列的每個塊,輸出將是這樣的:

Array 
(
    [0] => stdClass Object 
     (
      [users_info_id] => 1 
      [user_id] => 374 
      [user_email] => [email protected] 
      [phone] => 3213213213 
      [bt] => array (
       [firstname] => Foo 
       [lastname] => Faa 
       [vat_number] => 
       [country_code] => US 
       [address] => Jajajaja 
       [city] => KOKOKOKOKOKO 
       [state_code] => MD 
       [zipcode] => 20745 
       [phone] => 2401111111 
      ) 
      [st] => array (
       [firstname] => Foos 
       [lastname] => Faas 
       [vat_number] => 
       [country_code] => US 
       [address] => JSUSUSUS 
       [city] => LASOSLSL 
       [state_code] => DC 
       [zipcode] => 1234 
       [phone] => 1234567895 
      ) 
     ) 

我甚至不知道如何開始的代碼要做到這一點,另外,如果你注意到,ST和BT鍵從哪個是展會的關鍵address_type來到在第一個陣列中,ST是「送貨地址」,BT是賬單地址,一些用戶有一個船ping和一個帳單,但有一個用戶誰有3個或更多的地址發貨...
任何幫助將不勝感激。

+0

您是否考慮過使用多個查詢?抓住每個唯一的'users_info_id'並將它們存儲在一個數組中。然後遍歷該數組並查詢唯一的地址類型並將這些輸出存儲在同一個數組中? –

+0

因此,如果您使用'$ user ['users_info_id']'作爲$ user'作爲$ user'作爲數據庫查詢條件循環使用,則可以像'$ user [$ addressTypeFromDB] = $ dbRow;' –

回答

1

在這種情況下,我會用這樣一個循環:

$outputArray = array(); 

$previousUserId = -1; 

// Loop through all source records. 
foreach ($inputRows as $row) { 

    // If the current row has a different user id thn the row before, 
    // add the output row to the final output array and prepare a new output row. 
    // If the current row has the same user id as the row before, 
    // just add further address information. 
    // This handles also the start situation, $previousUserId = -1. 
    if ($previousUserId != $row->user_id) { 
     if ($previousUserId >= 0) { 
      $outputArray[] = $outputRow; 
     } 
     $outputRow = array(); 

     // Copy main attributes 
     $outputRow['users_info_id'] = $row->users_info_id; 
     $outputRow['user_id'] = $row->user_id; 
     $outputRow['user_email'] = $row->user_email; 
     $outputRow['phone'] = $row->phone; 
    } 

    $previousUserId = $row->user_id; 

    // Create a suitable address subarray and fill it. 
    if ($row->address_type == 'BT') { 
     $outputRow['bt'] = array(); 
     $outputRow['bt']['firstname'] = $row->firstname; 
     $outputRow['bt']['lastname'] = $row->lastname; 
     ... 
    } 
    if ($row->address_type == 'ST') { 
     // dito, but for ['st'] 
     // ... 
    } 
} 

這僅僅是一個結構,你將不得不去完成它。

代碼循環遍歷輸入表的每條記錄,我們稱之爲$inputRowsuser_id更改很重要,因爲這會啓動一個新的輸出行。只要user_id保持不變,代碼只會將更多地址類型添加到當前輸出行。所以,幾個輸入行被分組到一個輸出行。所有的輸出行然後被收集在一個$outputArray

請注意:

1)你在你的問題顯示轉儲顯示含有數組對象。在我的回答中,我創建了一個包含數組作爲輸出的數組。通常,我更喜歡僅僅使用關聯數組,因爲它們提供了更多的選擇名稱的自由。如果你想使用對象,只需相應地修改代碼即可。 ($outputObject->name = ...而不是$outputObject['name'] = ...)

2)I 假定 user_id條件與將輸入行分組到新的輸出行有關。我希望這是正確的;-D

編輯:如果有幾個記錄地址類型,還可以加上這樣一個附加陣列層:

... 
    ... 
    // Create a suitable address subarray and fill it. 
    if ($row->address_type == 'BT') { 
     // If the array that collects several bts has not been created, create it. 
     if (!isset($outputRow['bt']) { 
      $outputRow['bt'] = array(); 
     } 

     // Create an array with the bt address data 
     $addressData = array(); 
     $addressData['firstname'] = $row->firstname; 
     $addressData['lastname'] = $row->lastname; 
     ... 

     // Add the bt address data to the collection of bts. 
     $outputRow['bt'][] = $addressData; 
    } 
    if ($row->address_type == 'ST') { 
     // dito, but for ['st'] 
     // ... 
    } 

略有更高的要求,我建議外包將地址數據收集到自己的函數的部分,以便整個代碼保持可讀性。

+0

一樣存儲每行'謝謝,這是我的起點,正在工作,但是,如果用戶有超過1個ST或BT,它不會顯示它,只覆蓋那裏有什麼,所以我爲每個添加了一個「計數器」,$ cst = 0和$ cbt = 0,並在每個IF類型='BT'或ST內添加「總和」$ cst ++; ...如果用戶標識相同,則會按照代碼中的邏輯添加另一個鍵[0],[1] ...,直到用戶標識不同,「計數器」重置爲0,但是不工作,在第一個循環中顯示[bt] => array([7] ...),然後對於下一個用戶,它工作正常...有點奇怪... – Tanker

+0

對不起,對於遲到的答案...我我不確定你是否需要一個櫃檯(或者如果我理解這個要求的話)。請在代碼中查看我的建議。 –