0

I have two arrays:

$arr1 = [
    [
        'id' => 1,
        'name' => 'John',
        'email' => '[email protected]'
    ],
    [
        'id' => 2,
        'name' => 'Jane',
        'email' => '[email protected]'
    ]
];

And the second array:

$arr2 = [
    [
        'id' => 1,
        'email' => '[email protected]'
    ],
    [
        'id' => 2,
        'email' => '[email protected]'
    ],
    [
        'id' => 2,
        'email' => '[email protected]'
    ],
];

I would like to add all values with the same 'id' from the second array to the first array. The result I expect would be:

$arr3 = [
    [
        'id' => 1,
        'name' => 'John',
        'email' => ['[email protected]', '[email protected]']
    ],
    [
        'id' => 2,
        'name' => 'Jane',
        'email' => ['[email protected]', '[email protected]', '[email protected]']
    ]
];
1
  • It would be easier if you made the first array an associative array whose keys are the IDs. Then you can loop through the second array, find the corresponding element of the first array, and add the email to it. Commented Mar 1, 2019 at 1:31

2 Answers 2

1

This code will do what you want. It goes through all the entries of $arr2, looking for matching id values in $arr1 and, where it finds them, adding the email address from $arr2 to the list of emails in $arr1 for that id value:

foreach ($arr2 as $arr) {
    if (($k = array_search($arr['id'], array_column($arr1, 'id'))) !== false) {
        if (is_array($arr1[$k]['email'])) {
            $arr1[$k]['email'][] = $arr['email'];
        }
        else {
            $arr1[$k]['email'] = array($arr1[$k]['email'], $arr['email']);
        }
    }
}

Output:

Array (
    [0] => Array (
        [id] => 1 
        [name] => John
        [email] => Array (
            [0] => [email protected]
            [1] => [email protected]
        )
    )
    [1] => Array (
        [id] => 2
        [name] => Jane
        [email] => Array (
            [0] => [email protected]
            [1] => [email protected]
            [2] => [email protected]
        )
    )
)
Sign up to request clarification or add additional context in comments.

Comments

0

I agree with @Barmar's comment under the question; it will be more direct/efficient and boast a superior computational time complexity to iterate the second array to populate a lookup array and reference it while iterating the first array versus doing full scans and searches of the first array for every row of the second array.

This implementation forms the lookup array using array destructuring syntax in a body-less foreach() loop. Then another foreach() loop iterates the first array using array destructuring syntax, modifying the rows' email element, and checking if there are any emails to add to the first array's email.

Even if no corresponding row exists in the second array, the first array's email string will be cast as a single-element array for consistency.

Code: (Demo)

foreach ($arr2 as ['id' => $id, 'email' => $lookup[$id][]]);

foreach ($arr1 as ['id' => $id, 'email' => &$email]) {
    $email = array_merge((array) $email, $lookup[$id] ?? []);
}

var_export($arr1);

The name element does not need to be mentioned during array destructuring because there are no subsequent processes applied to it in the loops.

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.