将常规数组重建为多维数组

时间:2015-05-13 19:58:30

标签: php arrays multidimensional-array

我有一个数组,可以从单个表中输出DB中的信息,如下所示:

Array
(
    [0] => stdClass Object
        (
            [users_info_id] => 1
            [user_id] => 374
            [user_email] => foos@foo.com
            [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
              )
        )

我正在寻找的是重新构建该数组的每个块,因此输出将是这样的:

{{1}}

我甚至不知道如何启动代码来实现这一点,如果你注意到,ST和BT键来自第一个数组中显示的键address_type,ST代表“送货地址”和BT用于结算地址,有些用户有一个发货和一个用于结算,但有用户有3个或更多地址用于发货...
任何帮助将不胜感激。

1 个答案:

答案 0 :(得分: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']
      // ...
   }
}

这只是一个结构,你必须完成它。

代码循环遍历输入表的每条记录,让我们称之为$inputRows。重要的是user_id更改,因为这将启动新的输出行。只要user_id保持不变,代码就会将更多地址类型添加到当前输出行。因此,几个输入行被分组到一个输出行。然后,所有输出行都收集在$outputArray

请注意:

1)您在问题中显示的转储显示包含对象的数组。在我的回答中,我创建了一个包含数组作为输出的数组。通常,我更喜欢仅使用关联数组,因为它们在选择名称时提供了更多的自由。如果要使用对象,只需相应地更改代码即可。 ($outputObject->name = ...代替$outputObject['name'] = ...)

2)我假设 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']
      // ...
   }

如果需求略多,我建议将收集地址数据的部分外包给自己的函数,这样整个代码仍然可读。