How to Group a Multidimensional Array by a Particular Subarray Value

How to group a multidimensional array by a particular subarray value?

You need to group them by level first

Use foreach to loop into array check if the level is the same with the previous item then group it with that array

  $templevel=0;   

$newkey=0;

$grouparr[$templevel]="";

foreach ($items as $key => $val) {
if ($templevel==$val['level']){
$grouparr[$templevel][$newkey]=$val;
} else {
$grouparr[$val['level']][$newkey]=$val;
}
$newkey++;
}
print($grouparr);

The output of print($grouparr); will display like the format you hoped for

You can also try to

print($grouparr[7]);

Will display

 [7] => Array (
[4] => Array (
[cust] => XT7434
[type] => standard
)
)

Or

print($grouparr[3]);

Will display

[3] => Array (
[2] => Array (
[cust] => XT8922
[type] => premier
)

[3] => Array (
[cust] => XT8816
[type] => permier
)
)

PHP how to group a multidimensional array which value is same

Roughly like this:

$groupedItems = array();

foreach($data as $item)
{
$groupedItems[$item['property_id']][] = $item;
}

// See @Lepanto's comment below, this resets the keys to match output OP required:
$groupedItems = array_values($groupedItems);

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.

  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',
),
),
)

Group items in multidimensional array by same value at index

Array#forEach solution.





var arr = [["x","x", 1],["x","x", 2],["x","x", 2],["x","x", 3],["x","x", 3],["x","x", 3]], obj = {};


arr.forEach(v => (obj[v[2]] || (obj[v[2]] = [])).push(v));

var res = Object.keys(obj).map(v => obj[v]);


console.log(JSON.stringify(res));

How to group multidimensional array by sub-array value in and reassign keys in PHP

this should be enough, if I understood you right :)

$lines = file('./schedule.txt');

$employees = array();
foreach ($lines as $line)
{
$chunks = explode(',', $line);
$employees[$chunks[0]][] = array_slice($chunks, 1);
}

print_r($employees);

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;
}
}

PHP multidimensional array: group repeated values and create sub array

Nothing wrong with the code you've provided at the end, but here's some ideas for how to make it more tolerant to more array values (as you mentioned, phone, email, etc).

This uses the handy PHP array_diff_key function to remove the array elements you don't want from the "core" records. Then, applying array_diff_key to get those same array elements INTO the "company" records.

// set up the array of keys you don't want in the "original" record
$exclude = ['company' => FALSE, 'price' => FALSE];
// Your original loop
foreach($array as $v) {
// not strictly necessary, but helps readability
$id = $v['id'];
// Assign the "core" record all the values you want, excluding those defined above
// in this case, will remove "company" and "price"
$record = array_diff_key( $v, $exclude );

// only set this if not already set, otherwise wipes out previous companies
if ( ! isset($result[$id] ) ) {
$result[$id] = $record;
$result[$id]['companies'] = [];
}

// strip off the OTHER values from the array you don't want stored with the company
// this will automatically pick up the field NOT excluded above
// in this case, will remove all BUT "company" and "price"
$company = array_diff_key( $v, $record );
$result[$id]['companies'][] = $company;
}

Group array row on one column and form subarrays of varying depth/structure

UPDATE: Added a correction for the desired output at the bottom.

This seems easy, but is rather difficult to do right. The best approach is to divide and conquer. First collect the data together, which belongs together, and then make the nice JSON output. My first step is therefore this:

$input = [['color'=>'#000000','size'=>'L','count'=>2],
['color'=>'#000000','size'=>'XL','count'=>1],
['color'=>'#ffffff','size'=>'L','count'=>2],
['color'=>'#ffffff','size'=>'XL','count'=>1],
['color'=>'#ff0000','size'=>'L','count'=>1]];

$colors = [];

foreach ($input as $product) {
extract($product);
$colors[$color][$size] = $count;
}

echo json_encode($colors, JSON_PRETTY_PRINT);

This outputs:

Array
(
[#000000] => Array
(
[L] => 2
[XL] => 1
)

[#ffffff] => Array
(
[L] => 2
[XL] => 1
)

[#ff0000] => Array
(
[L] => 1
)

)

Please note that extract() should be used with care, since it can generate more variables than you bargained for, but it is very useful here. Never use it at the global scope, like I did here.

And now we turn this into the wanted JSON, like this:

$output = [];

foreach ($colors as $color => $sizes) {
$data = [];
foreach ($sizes as $size => $count) {
$data[] = ['value' => $size,
'count' => $count];
}
$output[] = ['color' => $color,
'size' => $data];
}

echo json_encode($output, JSON_PRETTY_PRINT);

This outputs:

[
{
"color": "#000000",
"size": [
{
"value": "L",
"count": 2
},
{
"value": "XL",
"count": 1
}
]
},
{
"color": "#ffffff",
"size": [
{
"value": "L",
"count": 2
},
{
"value": "XL",
"count": 1
}
]
},
{
"color": "#ff0000",
"size": [
{
"value": "L",
"count": 1
}
]
}
]

You might want to put all this code inside a function.

Here's a PHPFiddle.

NOTE: It is important to note that this code assumes that there are no duplicate color/size combinations in the input array.

In case the output you want wasn't a result of a typo, here's how you can modify the second loop to get it:

$output = [];

foreach ($colors as $color => $sizes) {
$data = [];
foreach ($sizes as $size => $count) {
$data[] = ['value' => $size,
'count' => $count];
}
if (count($data) == 1) {
$output[] = ['color' => $color,
'size' => $data[0]['value'],
'count' => $data[0]['count']];
} else {
$output[] = ['color' => $color,
'size' => $data];
}
}

echo json_encode($output, JSON_PRETTY_PRINT);

See this PHPFiddle

Group array by subarray values


$arr = array();

foreach ($old_arr as $key => $item) {
$arr[$item['id']][$key] = $item;
}

ksort($arr, SORT_NUMERIC);


Related Topics



Leave a reply



Submit