Reputation: 1316
If I wanted to associate items from one array with another array via identical values, eg. items.group_id -> groups.group_id, is there an array function to do that neatly?
I have two arrays:
$items = [
['group_id' => 456, 'item_id' => 123, /* Rest of details */],
['group_id' => 457, 'item_id' => 124, /* Rest of details */],
['group_id' => 457, 'item_id' => 125, /* Rest of details */],
['group_id' => 456, 'item_id' => 126, /* Rest of details */],
];
$groups = [
['group_id' => 456, 'group_name' => 'General'],
['group_id' => 457, 'group_name' => 'Ungeneral'],
];
And the result I want is:
$groups = [
[
'group_id' => 456,
'group_name' => 'General'
[
'item_id' => 123,
// Rest of details
],
[
'item_id' => 126,
// Rest of details
],
],
[
'group_id' => 457,
'group_name' => 'Ungeneral',
[
'item_id' => 124,
// Rest of details
],
[
'item_id' => 125,
// Rest of details
],
],
];
Upvotes: -1
Views: 259
Reputation: 47874
As an improvement on Amber's solution, I prefer to make references to each of the rows in the $groups
array, then iterate the $items
, isolate (and the remove) the identifying column value, the push the remaining elements of the item as a new subarray into its appropriate row reference. As Amber mentioned, isset()
is used to check if an item belongs in the $groups
array at all. Notice also that there are no furst level associative keys in my result.
Code: (Demo)
$items = [
['group_id' => 456, 'item_id' => 123, 'foo' => 'bar'],
['group_id' => 457, 'item_id' => 124, 'foo' => 'bar'],
['group_id' => 457, 'item_id' => 125, 'foo' => 'bar'],
['group_id' => 456, 'item_id' => 126, 'foo' => 'bar'],
];
$groups = [
['group_id' => 456, 'group_name' => 'General'],
['group_id' => 457, 'group_name' => 'Ungeneral'],
];
foreach ($groups as &$row) {
$ref[$row['group_id']] =& $row;
}
foreach ($items as $item) {
$id = $item['group_id'];
if (isset($ref[$id])) {
unset($item['group_id']);
$ref[$id][] = $item;
}
}
var_export($groups);
Output:
array (
0 =>
array (
'group_id' => 456,
'group_name' => 'General',
0 =>
array (
'item_id' => 123,
'foo' => 'bar',
),
1 =>
array (
'item_id' => 126,
'foo' => 'bar',
),
),
1 =>
array (
'group_id' => 457,
'group_name' => 'Ungeneral',
0 =>
array (
'item_id' => 124,
'foo' => 'bar',
),
1 =>
array (
'item_id' => 125,
'foo' => 'bar',
),
),
)
Upvotes: 0
Reputation: 1316
I found a solution that works for me, with some help from your solutions chaps.
$links_by_group = array();
foreach($links as $link) {
$linked_groups = $this->return_linked_groups($link['link_id']);
foreach($linked_groups as $group){
$links_by_group[$group][$link['link_id']] = $link;
}
}
Thanks for the help!
Upvotes: 0
Reputation: 106332
It would be easier if you keyed your groups array by the id instead of numerical indexes
$newArray = array();
foreach($groups as $group) {
// add the group, and an items array we can append to later.
$newArray[$group['group_id']] = $group;
$newArray[$group['group_id']]['items'] = array();
}
foreach ($items as $item) {
$newArray[$item['group_id']]['items'][] = $item;
}
Should result in an array like this:
$newArray = array(
[456] => array(
'group_id' => 456,
'group_name' => 'General'
'items' => array(
[0] => array(
'item_id' => 123,
// Rest of details
);
[1] => array(
'item_id' => 126,
// Rest of details
);
);
);
Upvotes: 2
Reputation: 526573
I don't think there's a built-in function to do this, but here's some basic code that should handle it:
<?php
// First, group the items by their group_id
$items_by_group = array();
foreach($items as $item) {
$items_by_group[$item['group_id']][] = $item;
}
// Second, go through the groups and if they have any associated items,
// add them to that group's array.
foreach($groups as $key => $value) {
if(isset($items_by_group[$value['group_id']])) {
foreach($items_by_group[$value['group_id']] as $ikey => $ivalue) {
unset($ivalue['group_id']);
$groups[$key][$ikey] = $ivalue;
}
}
}
?>
Note that the above code safely handles cases where you have items with an invalid group id (one for a group that's not defined - it'll ignore those items).
Upvotes: 4