-1

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
         ],
     ],
];

4 Answers 4

4

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).

Sign up to request clarification or add additional context in comments.

Comments

2

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

Comments

0

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!

Comments

0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.