Rafael Munoz
Rafael Munoz

Reputation: 656

PHP. Map two arrays using the attribute of one against the key of the second

I have two arrays:

The first one looks like this:

   Array: 8 [▼
      0 => array:17 [▼
        "id" => 4
        "firstname" => "Maria"
        "lastname" => "von Moszczenski"
        "slug" => "marianne-von-moszczenski"
        "email" => "[email protected]"
        "email_verified_at" => null
        "created_at" => "2019-11-21 17:34:53"
        "updated_at" => "2019-11-21 17:34:53"
        "deleted_at" => null
      ]
        1 => User {...}
        2 => User {...}
        3 => User {...}
        ... unknown number of elements
     ]

The second array looks like this:

array:8 [▼
  "Maria" => 17
  "Stefanie" => 2
  "Angela" => 3
  "Andrea" => 4
  "Michelle" => 5
  "Yvonne" => 6
  "Martina" => 7
  "Karolina" => 8
  ... unknown number of elements...
]

I want to merge both of them so, i get the following structure:

Array: 8 [▼
  0 => array:17 [▼
    "id" => 4
    "firstname" => "Maria"
    "lastname" => "von Moszczenski"
    "slug" => "marianne-von-moszczenski"
    "email" => "[email protected]"
    "email_verified_at" => null
    "created_at" => "2019-11-21 17:34:53"
    "updated_at" => "2019-11-21 17:34:53"
    "deleted_at" => null
    "total" => 17  // <------ this is the new field
    ... unknown number of elements...
  ]
    1 => User {...}
    2 => User {...}
    3 => User {...}
 ]

So i did this:

 foreach ($totalsPerEmployee as $key => $total) {
    foreach ($users as $user) { 
        if ($user['firstname'] === $key) {
            $user['totalappointments'] = $total;  // if I stop and echo hier I see the new field
        }
    }
}

If I echo the result of the foreach in the middle, I see that the new field is added, but once the two foreach end, the new field was not added.

My questions is:

This method looks to error prone or if the arrays get too big could lead to performance issues.

Is there any other way to map/combine/intersect or whatever these two arrays mapping one attribute (firstname) in the first one against the key of the second one?

if there is not any "magic" method and I have to make the two loops. What am I doing wrong?

Upvotes: 0

Views: 566

Answers (1)

Nigel Ren
Nigel Ren

Reputation: 57121

You can turn the loop round, you already have the totals array indexed by the user name, so just loop over the user array and if there is a value for it, then add it in...

foreach ($users as &$user) {
    if (isset($totalsPerEmployee[$user['firstname']])) {
        $user['totalappointments'] = $totalsPerEmployee[$user['firstname']];
    }
}
unset($user);

Also to ensure that you update the original array, using &$user uses a reference to the data, otherwise you (as you've found) update a copy of the data. Just to make sure - use unset($user) after the loop in case.

Upvotes: 2

Related Questions