问题
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["cartsall"]))){
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.
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.
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.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