Reputation: 1641
I need to group sets of data from my multidimensional array by ['DispensaryInventory']['product_id']
(or ['Product']['id']
) values and push grouped data into subarrays for DispensaryInventory
and ProductOption
.
My array:
$dispensary_inventory_data = [
[
'DispensaryInventory' => [
'id' => 15,
'dispensary_id' => 1,
'product_id' => 9,
'quantity' => '',
'price' => ''
],
'ProductOption' => ['value' => 2, 'unit' => 'oz'],
'Product' => ['id' => 9, 'name' => 'Bajaj']
],
[
'DispensaryInventory' => [
'id' => 11,
'dispensary_id' => 1,
'product_id' => 9,
'quantity' => 17,
'price' => 12.00
],
'ProductOption' => ['value' => '1/8', 'unit' => 'oz'],
'Product' => ['id' => 9, 'name' => 'Bajaj']
],
[
'DispensaryInventory' => [
'id' => 12,
'dispensary_id' => 1,
'product_id' => 9,
'quantity' => '',
'price' => ''
],
'ProductOption' => ['value' => '1/4', 'unit' => 'oz'],
'Product' => ['id' => 9, 'name' => 'Bajaj']
],
[
'DispensaryInventory' => [
'id' => 13,
'dispensary_id' => 1,
'product_id' => 9,
'quantity' => 5,
'price' => 123.00
],
'ProductOption' => ['value' => '1/2', 'unit' => 'oz'],
'Product' => ['id' => 9, 'name' => 'Bajaj']
],
[
'DispensaryInventory' => [
'id' => 14,
'dispensary_id' => 1,
'product_id' => 9,
'quantity' => '',
'price' => ''
],
'ProductOption' => ['value' => 1, 'unit' => 'oz'],
'Product' => ['id' => 9, 'name' => 'Bajaj']
],
[
'DispensaryInventory' => [
'id' => 5,
'dispensary_id' => 1,
'product_id' => 8,
'quantity' => '',
'price' => ''
],
'ProductOption' => ['value' => 2, 'unit' => 'oz'],
'Product' => ['id' => 8, 'name' => 'BMW']
],
[
'DispensaryInventory' => [
'id' => 1,
'dispensary_id' => 1,
'product_id' => 8,
'quantity' => 2,
'price' => 123.00
],
'ProductOption' => ['value' => '1/8', 'unit' => 'oz'],
'Product' => ['id' => 8, 'name' => 'BMW']
],
[
'DispensaryInventory' => [
'id' => 2,
'dispensary_id' => 1,
'product_id' => 8,
'quantity' => '',
'price' => ''
],
'ProductOption' => ['value' => '1/4', 'unit' => 'oz'],
'Product' => ['id' => 8, 'name' => 'BMW']
],
[
'DispensaryInventory' => [
'id' => 3,
'dispensary_id' => 1,
'product_id' => 8,
'quantity' => 23,
'price' => 222.00
],
'ProductOption' => ['value' => '1/2', 'unit' => 'oz'],
'Product' => ['id' => 8, 'name' => 'BMW']
],
[
'DispensaryInventory' => [
'id' => 4,
'dispensary_id' => 1,
'product_id' => 8,
'quantity' => 12,
'price' => 232.00
],
'ProductOption' => ['value' => 1, 'unit' => 'oz'],
'Product' => ['id' => 8, 'name' => 'BMW']
],
[
'DispensaryInventory' => [
'id' => 6,
'dispensary_id' => 1,
'product_id' => 3,
'quantity' => 3,
'price' => 21.00
],
'ProductOption' => ['value' => '1/8', 'unit' => 'oz'],
'Product' => ['id' => 3, 'name' => 'Yash product']
],
[
'DispensaryInventory' => [
'id' => 7,
'dispensary_id' => 1,
'product_id' => 3,
'quantity' => 12,
'price' => 56.00
],
'ProductOption' => ['value' => '1/4', 'unit' => 'oz'],
'Product' => ['id' => 3, 'name' => 'Yash product']
],
[
'DispensaryInventory' => [
'id' => 8,
'dispensary_id' => 1,
'product_id' => 3,
'quantity' => '',
'price' => ''
],
'ProductOption' => ['value' => '1/2', 'unit' => 'oz'],
'Product' => ['id' => 3, 'name' => 'Yash product']
],
[
'DispensaryInventory' => [
'id' => 9,
'dispensary_id' => 1,
'product_id' => 3,
'quantity' => 15,
'price' => 354.00
],
'ProductOption' => ['value' => 1, 'unit' => 'oz'],
'Product' => ['id' => 3, 'name' => 'Yash product']
],
[
'DispensaryInventory' => [
'id' => 10,
'dispensary_id' => 1,
'product_id' => 3,
'quantity' => '',
'price' => ''
],
'ProductOption' => ['value' => 2, 'unit' => 'oz'],
'Product' => ['id' => 3, 'name' => 'Yash product']
]
];
I want it to look like this array (with groups for 3, 8, and 9):
Array
(
[0] => Array
(
[DispensaryInventory] => Array
(
[0] => Array
(
[id] => 15
[dispensary_id] => 1
[product_id] => 9
[quantity] =>
[price] =>
)
[1] => Array
(
[id] => 11
[dispensary_id] => 1
[product_id] => 9
[quantity] => 17
[price] => 12.00
)
[2] => Array
(
[id] => 12
[dispensary_id] => 1
[product_id] => 9
[quantity] =>
[price] =>
)
[3] => Array
(
[id] => 13
[dispensary_id] => 1
[product_id] => 9
[quantity] => 5
[price] => 123.00
)
[4] => Array
(
[id] => 14
[dispensary_id] => 1
[product_id] => 9
[quantity] =>
[price] =>
)
)
[ProductOption] => Array
(
[0] => Array
(
[value] => 2
[unit] => oz
)
[1] => Array
(
[value] => 1/8
[unit] => oz
)
[2] => Array
(
[value] => 1/4
[unit] => oz
)
[3] => Array
(
[value] => 1/2
[unit] => oz
)
[4] => Array
(
[value] => 1
[unit] => oz
)
)
[Product] => Array
(
[id] => 9
[name] => Bajaj
)
)
[1] => Array
(
[DispensaryInventory] => Array
(
[0] => Array
(
[id] => 5
[dispensary_id] => 1
[product_id] => 8
[quantity] =>
[price] =>
)
[1] => Array
(
[id] => 1
[dispensary_id] => 1
[product_id] => 8
[quantity] => 2
[price] => 123.00
)
[2] => Array
(
[id] => 2
[dispensary_id] => 1
[product_id] => 8
[quantity] =>
[price] =>
)
[3] => Array
(
[id] => 3
[dispensary_id] => 1
[product_id] => 8
[quantity] => 23
[price] => 222.00
)
[4] => Array
(
[id] => 4
[dispensary_id] => 1
[product_id] => 8
[quantity] => 12
[price] => 232.00
)
)
[ProductOption] => Array
(
[0] => Array
(
[value] => 2
[unit] => oz
)
[1] => Array
(
[value] => 1/8
[unit] => oz
)
[2] => Array
(
[value] => 1/4
[unit] => oz
)
[3] => Array
(
[value] => 1/2
[unit] => oz
)
[4] => Array
(
[value] => 1
[unit] => oz
)
)
[Product] => Array
(
[id] => 8
[name] => BMW
)
)
[2] => Array
(
[DispensaryInventory] => Array
(
[0] => Array
(
[id] => 6
[dispensary_id] => 1
[product_id] => 3
[quantity] => 3
[price] => 21.00
)
[1] => Array
(
[id] => 7
[dispensary_id] => 1
[product_id] => 3
[quantity] => 12
[price] => 56.00
)
[2] => Array
(
[id] => 2
[id] => 8
[dispensary_id] => 1
[product_id] => 3
[quantity] =>
[price] =>
)
[3] => Array
(
[id] => 9
[dispensary_id] => 1
[product_id] => 3
[quantity] => 15
[price] => 354.00
)
[4] => Array
(
[id] => 10
[dispensary_id] => 1
[product_id] => 3
[quantity] =>
[price] =>
)
)
[ProductOption] => Array
(
[0] => Array
(
[value] => 2
[unit] => oz
)
[1] => Array
(
[value] => 1/8
[unit] => oz
)
[2] => Array
(
[value] => 1/4
[unit] => oz
)
[3] => Array
(
[value] => 1/2
[unit] => oz
)
[4] => Array
(
[value] => 1
[unit] => oz
)
)
[Product] => Array
(
[id] => 3
[name] => Yash product
)
)
My coding attempt:
foreach ($dispensary_inventory_data as $k1 => $a1) {
foreach ($dispensary_inventory_data as $k2 => $a2) {
if ($k1 < $k2 && $a1["DispensaryInventory"]["product_id"] == $a2["DispensaryInventory"]["product_id"]) {
$dispensary_inventory_data[$k1]["ProductOption"][] = $a2["ProductOption"];
$dispensary_inventory_data[$k1]["Product"][] = $a2["Product"];
if (isset($dispensary_inventory_data[$k1]["Product"]["id"])) {
$dispensary_inventory_data[$k1]["Product"][] = array(
"id" => $dispensary_inventory_data[$k1]["Product"]["id"],
"name" => $dispensary_inventory_data[$k1]["Product"]["name"],
"quantity" => $dispensary_inventory_data[$k1]["Product"]["quantity"]
);
$dispensary_inventory_data[$k1]["ProductOption"][] = array(
"id" => $dispensary_inventory_data[$k1]["ProductOption"]["id"],
"value" => $dispensary_inventory_data[$k1]["ProductOption"]["value"],
"unit" => $dispensary_inventory_data[$k1]["ProductOption"]["unit"]
);
unset($dispensary_inventory_data[$k1]["Product"]["id"]);
unset($dispensary_inventory_data[$k1]["Product"]["name"]);
unset($dispensary_inventory_data[$k1]["Product"]["city"]);
unset($dispensary_inventory_data[$k1]["Product"]["quantity"]);
unset($dispensary_inventory_data[$k1]["ProductOption"]["id"]);
unset($dispensary_inventory_data[$k1]["ProductOption"]["value"]);
unset($dispensary_inventory_data[$k1]["ProductOption"]["unit"]);
}
unset($dispensary_inventory_data[$k2]);
}
}
}
Upvotes: 1
Views: 111
Reputation: 47874
I recommend grouping by product_id
values by pushing references into the result array. If a particular product_id hasn't been encountered before, declare the first data set as desired and push that set into the result array by reference. When a particular product_id is subsequently encountered, push the new data into the reference instead of the result array. This has the benefit of not applying temporary keys to the result array.
The Product
data doesn't change after the first encounter and you've asked to leave this subarray as a single entry, so that data is not later added to the reference variable.
Code: (Demo)
$result = [];
foreach ($array as $set) {
$group = $set['DispensaryInventory']['product_id'];
if (!isset($ref[$group])) {
$ref[$group] = [
'DispensaryInventory' => [$set['DispensaryInventory']], // make into a subarray
'ProductOption' => [$set['ProductOption']], // make into a subarray
'Product' => $set['Product'] // leave as-id
];
$result[] =& $ref[$group]; // push reference into result array
} else {
$ref[$group]['DispensaryInventory'][] = $set['DispensaryInventory']; // push new data into subarray
$ref[$group]['ProductOption'][] = $set['ProductOption']; // push new data into subarray
}
}
var_export($result);
Upvotes: 0
Reputation: 16216
You can use a php array_column function and reorganize your array into a new array with required structure and minimal effort:
$result = array();
$result['DispensaryInventory'] = array_column($data, 'DispensaryInventory');
$result['ProductOption'] = array_column($data, 'ProductOption');
$result['Product'] = array_column($data, 'Product');
Upvotes: 1
Reputation: 8325
updated after clarifications
use this fnction to convert the array to the format you need:
function my_format($data)
{
$data2 = array();
foreach($data as $val)
{
$keys = array_keys($val);
// you can also use $val['DispensaryInventory']['product_id'] here,
// but i take it these refer to the same thing
$product_id = $val['Product']['id'];
if (!isset($data2[$product_id])) $data2[$product_id] = array();
foreach($keys as $key)
{
if ( 'Product' === $key ) $data2[$product_id][$key] = $val[$key];
elseif ( !isset($data2[$product_id][$key]) ) $data2[$product_id][$key] = array($val[$key]);
else $data2[$product_id][$key][] = $val[$key];
}
}
return array_values($data2); // you can also return the $data2 here
}
use like this:
$new_data = my_format($data);
(expected) output (did not test)
Array
(
[0] => Array
(
[DispensaryInventory] => Array
(
[0] => Array
(
[id] => 15
[dispensary_id] => 1
[product_id] => 9
[quantity] =>
[price] =>
)
[1] => Array
(
[id] => 11
[dispensary_id] => 1
[product_id] => 9
[quantity] => 17
[price] => 12.00
)
[2] => Array
(
[id] => 12
[dispensary_id] => 1
[product_id] => 9
[quantity] =>
[price] =>
)
[3] => Array
(
[id] => 13
[dispensary_id] => 1
[product_id] => 9
[quantity] => 5
[price] => 123.00
)
[4] => Array
(
[id] => 14
[dispensary_id] => 1
[product_id] => 9
[quantity] =>
[price] =>
)
)
[ProductOption] => Array
(
[0] => Array
(
[value] => 2
[unit] => oz
)
[1] => Array
(
[value] => 1/8
[unit] => oz
)
[2] => Array
(
[value] => 1/4
[unit] => oz
)
[3] => Array
(
[value] => 1/2
[unit] => oz
)
[4] => Array
(
[value] => 1
[unit] => oz
)
)
[Product] => Array
(
[id] => 9
[name] => Bajaj
)
)
[1] => Array
(
[DispensaryInventory] => Array
(
[0] => Array
(
[id] => 5
[dispensary_id] => 1
[product_id] => 8
[quantity] =>
[price] =>
)
[1] => Array
(
[id] => 1
[dispensary_id] => 1
[product_id] => 8
[quantity] => 2
[price] => 123.00
)
[2] => Array
(
[id] => 2
[dispensary_id] => 1
[product_id] => 8
[quantity] =>
[price] =>
)
[3] => Array
(
[id] => 3
[dispensary_id] => 1
[product_id] => 8
[quantity] => 23
[price] => 222.00
)
[4] => Array
(
[id] => 4
[dispensary_id] => 1
[product_id] => 8
[quantity] => 12
[price] => 232.00
)
)
[ProductOption] => Array
(
[0] => Array
(
[value] => 2
[unit] => oz
)
[1] => Array
(
[value] => 1/8
[unit] => oz
)
[2] => Array
(
[value] => 1/4
[unit] => oz
)
[3] => Array
(
[value] => 1/2
[unit] => oz
)
[4] => Array
(
[value] => 1
[unit] => oz
)
)
[Product] => Array
(
[id] => 8
[name] => BMW
)
)
[2] => Array
(
[DispensaryInventory] => Array
(
[0] => Array
(
[id] => 6
[dispensary_id] => 1
[product_id] => 3
[quantity] => 3
[price] => 21.00
)
[1] => Array
(
[id] => 7
[dispensary_id] => 1
[product_id] => 3
[quantity] => 12
[price] => 56.00
)
[2] => Array
(
[id] => 2
[id] => 8
[dispensary_id] => 1
[product_id] => 3
[quantity] =>
[price] =>
)
[3] => Array
(
[id] => 9
[dispensary_id] => 1
[product_id] => 3
[quantity] => 15
[price] => 354.00
)
[4] => Array
(
[id] => 10
[dispensary_id] => 1
[product_id] => 3
[quantity] =>
[price] =>
)
)
[ProductOption] => Array
(
[0] => Array
(
[value] => 2
[unit] => oz
)
[1] => Array
(
[value] => 1/8
[unit] => oz
)
[2] => Array
(
[value] => 1/4
[unit] => oz
)
[3] => Array
(
[value] => 1/2
[unit] => oz
)
[4] => Array
(
[value] => 1
[unit] => oz
)
)
[Product] => Array
(
[id] => 3
[name] => Yash product
)
)
Upvotes: 1