1

I have two arrays like:

$team = [
    ['id' => 1, 'name' => 'Team A'],
    ['id' => 2, 'name' => 'Team B'],
    ['id' => 3, 'name' => 'Team C'], 
]; 

$people = [
    ['id' => 1, 'name' => 'Mark Hamill', 'team' => 1],
    ['id' => 2, 'name' => 'Nicolas Cage', 'team' => 2],
    ['id' => 3, 'name' => 'Tom Cruise', 'team' => 3],
    ['id' => 4, 'name' => 'Tom Hanks', 'team' => 1],
    ['id' => 5, 'name' => 'Brad Pitt', 'team' => 2],
    ['id' => 6, 'name' => 'Paul Smith', 'team' => 3],
    ['id' => 7, 'name' => 'Matt Daemon', 'team' => 1],
    ['id' => 8, 'name' => 'Robert Redford', 'team' => 2],
]  

I would like to merge the $people array into the $team array as a child node based on the team id. So the result would be:

$team = [
    [
        'id' => 1, 
        'name' =>'Team A',
        'members' => [
            ['id' => 1, 'name' => 'Mark Hamill', 'team' => 1],
            ['id' => 4, 'name' => 'Tom Hanks', 'team' => 1],
            ['id' => 7, 'name' => 'Matt Daemon', 'team' => 1],
        ]
    ],
    [
        'id' => 2, 
        'name' =>'Team B',
        'members' => [
            ['id' => 2, 'name' => 'Nicolas Cage', 'team' => 2],
            ['id' => 5, 'name' => 'Brad Pitt', 'team' => 2],
            ['id' => 8, 'name' => 'Robert Redford', 'team' => 2],
        ]
    ],
    [
        'id' => 3, 
        'name' =>'Team C',
        'members' => [
            ['id' => 3, 'name' => 'Tom Cruise', 'team' => 3],
            ['id' => 6, 'name' => 'Paul Smith', 'team' => 3],
        ]
    ], 
]; 

I know I can loop through $team and add the relevant $people one at a time based on their 'team' id, but I was wondering if there was a more efficient way of doing this. In my project, either of the arrays could grow to contain up to around 50 items each and processing these one at a time is really slowing the page down.

Thanks

5
  • Well I'd say the first thing you need to do is translate your "mater" array to be indexed by your ID, and then you can simply iterate over your secondary array and update the records by key. Commented Aug 15, 2018 at 11:20
  • please share your try ? Commented Aug 15, 2018 at 11:28
  • Anyway you must visit each person once. That algorithm can't be more efficient than linear Commented Aug 15, 2018 at 11:35
  • 1
    I didn't notice the efficient part. That makes the question off topic. Commented Aug 15, 2018 at 11:36
  • If you write your own implementation, you can try to ask at Code Review Commented Aug 15, 2018 at 11:37

2 Answers 2

4

This will loop your $teams array and intersect with an array_column to get the arrays you want.

$teampeople = array_column($people, "team");
//Creates a lookup array of the teams from people array

foreach($team as &$t){
    // Here I match from the lookup array and get the "main" arrays.  
    // Array_values remove the indexed from the resulting array to make it 0,1,2 etc.
    $t['members'] = array_values(array_intersect_key($people, array_intersect($teampeople, [$t['id']])));
}
unset($t); // just to make sure you don't accidentally change the array
var_dump($team);

Outputs:

array(3) {
  [0]=>
  array(3) {
    ["id"]=>
    int(1)
    ["name"]=>
    string(6) "Team A"
    ["members"]=>
    array(3) {
      [0]=>
      array(3) {
        ["id"]=>
        int(1)
        ["name"]=>
        string(11) "Mark Hamill"
        ["team"]=>
        int(1)
      }
      [1]=>
      array(3) {
        ["id"]=>
        int(4)
        ["name"]=>
        string(9) "Tom Hanks"
        ["team"]=>
        int(1)
      }
      [2]=>
      array(3) {
        ["id"]=>
        int(7)
        ["name"]=>
        string(11) "Matt Daemon"
        ["team"]=>
        int(1)
      }
    }
  }
  [1]=>
  array(3) {
    ["id"]=>
    int(2)
    ["name"]=>
    string(6) "Team B"
    ["members"]=>
    array(3) {
      [0]=>
      array(3) {
        ["id"]=>
        int(2)
        ["name"]=>
        string(12) "Nicolas Cage"
        ["team"]=>
        int(2)
      }
      [1]=>
      array(3) {
        ["id"]=>
        int(5)
        ["name"]=>
        string(9) "Brad Pitt"
        ["team"]=>
        int(2)
      }
      [2]=>
      array(3) {
        ["id"]=>
        int(8)
        ["name"]=>
        string(14) "Robert Redford"
        ["team"]=>
        int(2)
      }
    }
  }
  [2]=>
  &array(3) {
    ["id"]=>
    int(3)
    ["name"]=>
    string(6) "Team C"
    ["members"]=>
    array(2) {
      [0]=>
      array(3) {
        ["id"]=>
        int(3)
        ["name"]=>
        string(10) "Tom Cruise"
        ["team"]=>
        int(3)
      }
      [1]=>
      array(3) {
        ["id"]=>
        int(6)
        ["name"]=>
        string(10) "Paul Smith"
        ["team"]=>
        int(3)
      }
    }
  }
}

https://3v4l.org/kmvuR

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

1 Comment

Awesome. Thanks for your help
0

try this:

foreach ($team as $t) {
    $t['members'] = array_filter($people, function ($var) use ($t) {
    return ($var['team'] == $t['id']);
})
}

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.