Group array data by column value and only create indexed subarrays if more than one occurrence

狂风中的少年 提交于 2021-01-28 07:09:00

问题


I need to group my multidimensional array by dates.

For example:

Array
(    
    [0] => Array
        (
            [product_id] => 52
            [date] => 2017-07-28
        )
    [1] => Array
        (
            [product_id] => 53
            [date] => 2017-07-30
        )
    [2] => Array
        (
            [product_id] => 123
            [date] => 2017-07-30
        )
)

I need this result:

Array
(
     [2017-07-30] => Array
        (
            [0] => Array
                (
                    [product_id] => 123
                    [date] => 2017-07-30
                )
            [1] => Array
                (
                    [product_id] => 53
                    [date] => 2017-07-30
                )
        )    
    [2017-07-28] => Array
        (
            [product_id] => 52
            [date] => 2017-07-28
        )
)

This is my coding attempt:

foreach($products as $product){
    $array = array($product['date']=>array('pid'=>$product['product_id'])‌​); 
    if(!empty($deliverdates)){ 
        if(in_array($product['date'],array_keys($_SESSION["carts‌​all"]))){ 
            foreach($deliverdates as $k => $v){
                if($product['date'] == $k){
                    array_push($deliverdates[$k], $array);
                }
            }
        }else{
            $deliverdates = array_merge($deliverdates,$array);
        }
    }else{
        $deliverdates = $array;
    }
}

回答1:


Your desired output array structure seems a little strange and I feel like it would make iterating it more complex than it needs to be -- but oh well.

Iterate the input array, and use the date values as keys to help you to group the data and swiftly determine if a given date is being encountered for the first time. An isset() call is going to be the fastest way forward.

  1. If the date has not been encountered yet, simply store the subarray in the result array and assign it a new key using the date.

  2. If the date has been encountered before, then you can perform another quick check to see if the previously stored data (respective to the given date) has the product_id key -- this means it is an associative array and therefore contains only one "set" of data. In this case, a structure change will need to occur. The existing associative array for that date will need to be merged with the new associative array to form a deeper structure. The end result for this iteration will be that the date's data structure becomes an index two-element array of associative arrays.

  3. After a given date has the new "indexed array of associative arrays" stucture, any subsequent encounters of the date are simply pushed into the indexed array using bracket-syntax.

Code: (Demo)

$array = [
    ['product_id' => 52, 'date' => '2017-07-28'],
    ['product_id' => 53, 'date' => '2017-07-30'],
    ['product_id' => 81, 'date' => '2017-07-26'],
    ['product_id' => 123, 'date' => '2017-07-30'],
    ['product_id' => 59, 'date' => '2017-07-26'],
    ['product_id' => 124, 'date' => '2017-07-30']
];

foreach ($array as $subarray) {
    $date = $subarray['date'];                         // not strictly necessary, but may aid code readability
    if (!isset($result[$date])) {
        $result[$date] = $subarray;                    // first encounter means no index
    } elseif (isset($result[$date]['product_id'])) {   // if associative, make indexed with associative subarrays
        $result[$date] = [$result[$date], $subarray];  // second encounter means structural change to indexed subarrays
    } else {
        $result[$date][] = $subarray;                  // beyond second encounter means push subarray into indexed structure
    }
}
krsort($result);                                       // it appears that you want DESC order
var_export($result);

Output:

array (
  '2017-07-30' => 
  array (
    0 => 
    array (
      'product_id' => 53,
      'date' => '2017-07-30',
    ),
    1 => 
    array (
      'product_id' => 123,
      'date' => '2017-07-30',
    ),
    2 => 
    array (
      'product_id' => 124,
      'date' => '2017-07-30',
    ),
  ),
  '2017-07-28' => 
  array (
    'product_id' => 52,
    'date' => '2017-07-28',
  ),
  '2017-07-26' => 
  array (
    0 => 
    array (
      'product_id' => 81,
      'date' => '2017-07-26',
    ),
    1 => 
    array (
      'product_id' => 59,
      'date' => '2017-07-26',
    ),
  ),
)


来源:https://stackoverflow.com/questions/45264777/group-array-data-by-column-value-and-only-create-indexed-subarrays-if-more-than

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!