将常规阵列重建为多维阵列



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

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

我什至不知道如何启动代码以实现这一目标,而且,如果您注意到ST和BT键来自第一个数组中显示的密钥地址_type,ST是"运输地址"BT用于计费地址,一些用户有一笔运费,有一笔用于计费,但是有些用户有3个或更多的运输地址...
任何帮助将不胜感激。

在这种情况下,我会使用这样的循环:

$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)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']
      // ...
   }

有了更多的要求,我建议外包将地址数据收集到自己功能的部分外包,以使整个代码保持可读。

最新更新