冷凝,重组和添加子阵列

时间:2015-08-26 18:50:15

标签: php arrays multidimensional-array

我一直在摸不着头脑,为我的阵列结构问题提出解决方案而惨遭失败。我不确定尝试修复哪个部分会更好,事后是从SQL或PHP数组返回的数据。

我的SQL数据返回如下:

$i = 0;
while ( $row = sqlsrv_fetch_array( $stmt, SQLSRV_FETCH_ASSOC ) ) {
            $colData[$i] = array(
                    'name' => $row['FULLNAME'],
                    'invoice' => $row['CUST_InvoiceNumber_020911544'],
                    array(
                        'service' => $row['CUST_Service_052400634'],
                        'date' => date_normalizer($row['CUST_ServiceDate_064616924']),
                        'service_amount' =>  $row['CUST_ServiceAmount_054855553'],
                    ),
                    'do_all_for' => $row['CUST_DoAllFor_021206685'],
                    'memo' => $row['CUST_Memo_021614200'],
                    'paymenttype' => $row['CUST_PAYMENTTYPE_123838203'],
                    'deposit' => $row['CUST_DEPOSIT_124139703'],
                    'datepaid' => date_normalizer($row['CUST_DATEPAID_124941578']),
                );
            $i++;
        }

结果数组具有以下结构:

array (
  0 => 
  array (
    'name' => 'ABRAHAM PRETORIS',
    'invoice' => '63954',
    0 => 
    array (
      'service' => 'Tree Work',
      'date' => '2015-01-22',
      'service_amount' => '1305.00',
    ),
    'do_all_for' => '4924.68',
    'memo' => 'CHECK #947 $2400',
    'paymenttype' => 'VISA',
    'deposit' => '4429.48',
    'datepaid' => '2015-02-09',
  ),
  1 => 
  array (
    'name' => 'ABRAHAM PRETORIS',
    'invoice' => '63954',
    0 => 
    array (
      'service' => 'DRF',
      'date' => '2015-01-22',
      'service_amount' => '740.00',
    ),
    'do_all_for' => '4924.68',
    'memo' => 'CHECK #947 $2400',
    'paymenttype' => 'VISA',
    'deposit' => '4429.48',
    'datepaid' => '2015-02-09',
  ),
  2 => 
  array (
    'name' => 'ABRAHAM PRETORIS',
    'invoice' => '63954',
    0 => 
    array (
      'service' => 'Stumps',
      'date' => '2015-01-26',
      'service_amount' => '360.00',
    ),
    'do_all_for' => '4924.68',
    'memo' => 'CHECK #947 $2400',
    'paymenttype' => 'VISA',
    'deposit' => '4429.48',
    'datepaid' => '2015-02-09',
  ),

请注意,我为同一个人创建了一个新的子阵列,因为子子阵列(service,date& service_amount)有多个值。 我想要完成的是缩小阵列,以便我只有一个阵列用于" ABRAHAM PRETORIS"等,但所有不同的服务列为子数组。我希望它看起来像这样:

array (
  0 => 
  array (
    'name' => 'ABRAHAM PRETORIS',
    'invoice' => '63954',
    0 => 
    array (
      'service' => 'Tree Work',
      'date' => '2015-01-22',
      'service_amount' => '1305.00',
    ),
    1 =>
    array (
      'service' => 'DRF',
      'date' => '2015-01-22',
      'service_amount' => '740.00',
    ),
    2 =>
    array (
      'service' => 'STUMPS',
      'date' => '2015-01-26',
      'service_amount' => '360.00',
    ),
    'do_all_for' => '4924.68',
    'memo' => 'CHECK #947 $2400',
    'paymenttype' => 'VISA',
    'deposit' => '4429.48',
    'datepaid' => '2015-02-09',
  ),

我已经查看了大量嵌套的foreach语句和php数组函数的例子,但是我无法绕过如何循环并将其他服务添加到数组然后继续#&# 39;具有不同名称和/或发票号的行。 在此先感谢您的帮助!!

1 个答案:

答案 0 :(得分:3)

首先,确保您的SQL查询具有order by name, invoice。这将确保您要分组的所有记录都是顺序的。

然后你必须创建一个带有一些额外内部逻辑的循环:

// Creates an array to hold the final array.
$result = array();
// This var will keep track of name changes.
$current_name = '';
while ( $row = sqlsrv_fetch_array( $stmt, SQLSRV_FETCH_ASSOC ) ) 
{
  // Let's check if the name changed. This will be true for the first
  // time the loop runs.
  if($current_name != $row['FULLNAME'])
  {
    // If we are beginning, the if below will not run. But in subsequent 
    // records, it will add the acumulated array to the main result.
    if($current_name != '') $result[] = $temp;
    // The temp array will be populated with all data that DOES NOT change 
    // for the current name.
    $temp = array('name' => $row['FULLNAME'],
                  'invoice' => $row['CUST_InvoiceNumber_020911544'],
                  'do_all_for' => $row['CUST_DoAllFor_021206685'],
                  'memo' => $row['CUST_Memo_021614200'],
                  'paymenttype' => $row['CUST_PAYMENTTYPE_123838203'],
                  'deposit' => $row['CUST_DEPOSIT_124139703'],
                  'datepaid' => date_normalizer($row['CUST_DATEPAID_124941578']),
                 );
    // Update the current name.
    $current_name = $row['FULLNAME'];
  }
  // The part that runs only on name changes has finished. From now on, we
  // will take care of data which will be accumulated 
  // in a sub-array (until name changes and the block above resets it).
  $temp['sub-array'][] = 
      array('service' => $row['CUST_Service_052400634'],
              'date' => date_normalizer($row['CUST_ServiceDate_064616924']),
              'service_amount' => $row['CUST_ServiceAmount_054855553']);
}
// After the loop, the last temp array needs to be added too.
$result[] = $temp;

这是一般概念:您将创建一个临时数组来保存当前名称,您将在其中填充其他数据。一旦名称发生变化,累计数据将被转储到主结果,重置临时数组,并开始新的累积。

我现在无法测试代码,因此可能需要一些修复,但这种方法效果很好,我的观点是向您展示这个概念,以便您可以根据自己的具体需求进行调整。