How to group subarrays by a column value?
There is no native one, just use a loop.
$result = array();
foreach ($data as $element) {
$result[$element['id']][] = $element;
}
Group and merge subarray data based on one column value
A simple loop should do this..
$group = [];
foreach ($data as $item) {
if (!isset($group[$item['date']])) {
$group[$item['date']] = [];
}
foreach ($item as $key => $value) {
if ($key == 'date') continue;
$group[$item['date']][$key] = $value;
}
}
Group array rows by column value and create subarrays in each group
You can do this way.
$inputArray = array("0"=>array('record_id'=>'3','task_date'=>'28-10-02'),'1'=>array('record_id'=>'3','task_date'=>'28-10-02'),'2'=>array('record_id'=>'3','task_date'=>'28-10-03'));
$outputArray = array();
foreach($inputArray as $key=>$value){
$outputArray[$value['task_date']][]=$value;
}
print_r(array_values($outputArray));
Group array rows by column value and push whole rows as subarrays within the group
Here's a fairly concise solution based on some built-in PHP array handling functions (array_map
, array_filter
, array_unique
and array_column
). It uses array_column
and array_unique
to get a list of distinct invoice_id
values, then array_map
to generate the output, filtering the input array for each entry based on whether the invoice_id
values match:
$items = array_map(function ($inv_id) use ($item) {
return array('invoice_id' => $inv_id,
'group' => array_filter($item,
function ($itm) use ($inv_id) {
return $itm['invoice_id'] == $inv_id;
})
);
}, array_unique(array_column($item, 'invoice_id'))
);
Output:
Array
(
[0] => Array
(
[invoice_id] => 72,
[group] => Array
(
[0] => Array
(
[invoice_id] => 72,
[item] => SN00001
)
)
)
[1] => Array
(
[invoice_id] => 73,
[group] => Array
(
[1] => Array
(
[invoice_id] => 73,
[item] => SN00002
)
[2] => Array
(
[invoice_id] => 73,
[item] => SN00003
)
[3] => Array
(
[invoice_id] => 73,
[item] => SN00004
)
)
)
[4] => Array
(
[invoice_id] => 74,
[group] => Array
(
[4] => Array
(
[invoice_id] => 74,
[item] => SN00005
)
[5] => Array
(
[invoice_id] => 74,
[item] => SN00006
)
)
)
)
Note that internal array numbering does not start at 0
; if you need that then add array_values
to re-index in the appropriate places:
$items = array_values(array_map(function ($inv_id) use ($item) {
return array('invoice_id' => $inv_id,
'group' => array_values(array_filter($item,
function ($itm) use ($inv_id) {
return $itm['invoice_id'] == $inv_id;
}))
);
}, array_unique(array_column($item, 'invoice_id'))
));
Demo on 3v4l.org
How to group subarrays using values from two columns then sum a third column's values?
You only need to build compound temporary keys and then overwrite the keys.
By writing an initial element (null
in this case) then deleting the element after the loop is finished, you ensure that the first key in the result array is 1
.
To avoid the "messiness" of the repeated long-winded compound key, you can save the the dynamic key as a variable in the first line inside of the foreach loop, then reference that variable in the three respective locations in the condition block.
Code (Demo)
$array = [
1 => ['quantity' => 2, 'product_id' => 1, 'option_id' => 22],
2 => ['quantity' => 2, 'product_id' => 2, 'option_id' => 22],
3 => ['quantity' => 3, 'product_id' => 2, 'option_id' => 22],
4 => ['quantity' => 1, 'product_id' => 2, 'option_id' => 25]
];
$result = [null]; // create placeholding element
foreach($array as $subarray){
$composite_key = $subarray['product_id'] . '_' . $subarray['option_id'];
if(!isset($result[$composite_key])){
$result[$composite_key] = $subarray; // first occurrence
}else{
$result[$composite_key]['quantity'] += $subarray['quantity']; // not first occurrence
}
}
$result=array_values($result); // change from assoc to indexed
unset($result[0]); // remove first element to start numeric keys at 1
var_export($result);
Output:
array (
1 =>
array (
'quantity' => 2,
'product_id' => 1,
'option_id' => 22,
),
2 =>
array (
'quantity' => 5,
'product_id' => 2,
'option_id' => 22,
),
3 =>
array (
'quantity' => 1,
'product_id' => 2,
'option_id' => 25,
),
)
Group subarrays based on column value
You more or less have what I would have arrived at for a solution.
As long as the data that you wish to use as an index will always be in the same position in the array, you will be able to hardcode the index as you have done in the collector array.
If not, I would think about moving to an associative array and assigning a name to the value that you want to use as an index when creating the array.
[['a', 'index'=>1] [etc...]]
$out[$i[index]][] = $i;
Group array data by column value and only create indexed subarrays if more than one occurrence
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',
),
),
)
Group array by subarray values
$arr = array();
foreach ($old_arr as $key => $item) {
$arr[$item['id']][$key] = $item;
}
ksort($arr, SORT_NUMERIC);
Group row data by one column value and populate a subarray in each group with the other column value
This should do the trick
$args = array
(
array( 'type' => 'AAA', 'label_id' => 'A1,35' ),
array( 'type' => 'AAA', 'label_id' => 'A2,34' ),
array( 'type' => 'BBB', 'label_id' => 'B1,29' ),
array( 'type' => 'CCC', 'label_id' => 'C1,20' ),
array( 'type' => 'CCC', 'label_id' => 'C2,19' ),
array( 'type' => 'CCC', 'label_id' => 'C3,18' )
);
$tmp = array();
foreach($args as $arg)
{
$tmp[$arg['type']][] = $arg['label_id'];
}
$output = array();
foreach($tmp as $type => $labels)
{
$output[] = array(
'type' => $type,
'label_id' => $labels
);
}
var_dump($output);
The output is :
array
0 =>
array
'type' => string 'AAA' (length=3)
'label_id' =>
array
0 => string 'A1,35' (length=5)
1 => string 'A2,34' (length=5)
1 =>
array
'type' => string 'BBB' (length=3)
'label_id' =>
array
0 => string 'B1,29' (length=5)
2 =>
array
'type' => string 'CCC' (length=3)
'label_id' =>
array
0 => string 'C1,20' (length=5)
1 => string 'C2,19' (length=5)
2 => string 'C3,18' (length=5)
Related Topics
Send Email With PHP from HTML Form on Submit With the Same Script
How to Retrieve Images from MySQL Database and Display in an HTML Tag
Search Form With One or More (Multiple) Parameters
If Block Inside Echo Statement
Calculate Math Expression from a String Using Eval
Calling Closure Assigned to Object Property Directly
Woocommerce: Auto Complete Paid Orders
Using a String Path to Set Nested Array Data
Get $_Post from Multiple Checkboxes
Remove a Child With a Specific Attribute, in Simplexml For PHP
How to Check If a Url Exists Via PHP
Creating One Array from Another Array in PHP
PHP 7.2 Function Create_Function() Is Deprecated
PHP Sort a Multidimensional Array by Element Containing Y-M-D H:I:S Date