1

I am wanting to merge 2 arrays that may or may not share the same values, and may or may not have the same keys.

If a key exist in both arrays, I want to merge both values. If a key doesn't exist in the other, I want to add it to the array, adding the missing key/value.

In the below example, Array A and Array B share a common user_key.

But Array A has a taken_count KVP, and Array B has release_count KVP.

I want a new array that uses the user_key KVP as the array key. If a KVP exists in one array but not the other, I want to add it to the `user_key'.

You can see that user 1111 is in both arrays, so his user_name, taken_count and release_count is added to the new array.

Person B doesn't exist in Array B, so person B's is added to the new array and the release_count KVP is added with 0

Same for C.

I have tried multiple variations on array_merge_recursive, but it doesn't add the missing keys.

I use the below foreach to loop through all the calls released then I use another foreach that loops through all the taken. But some KVPs are missing.

foreach ($calls_released_by_user as $key=>$value){
        $user_name     = array_key_exists($key, $calls_taken_by_user) ? $calls_taken_by_user[$key]['user_name']  : 0
        $taken_count   = array_key_exists($key, $calls_taken_by_user) ? $calls_taken_by_user[$key]['taken_count']  : 0;
        $release_count = array_key_exists($key, $calls_released_by_user)  ?  $calls_released_by_user[$key]['release_count'] : 0;


        $all_user_calls_counts[$key] =  array(  'user_name'=>$value['user_name'],
                                                'taken_count' => $taken_count,
                                                'release_count' => $release_count);


    }

ARRAY A

[0]=>
{
    ["user_key"]    =>   "1111"    
    ["user_name"]   =>  "A Person"
    ["taken_count"] =>   "10"
}
[1]=>
{
    ["user_key"]    =>  "2222"    
    ["user_name"]   =>  "B Person"
    ["taken_count"] =>   "20"
}

ARRAY B

[0]=>
{
    ["user_key"]        => "1111"    
    ["user_name"]       => "A Person"
    ["release_count"]   => "5"
}
[1]=>
{
    ["user_key"]        => "3333"    
    ["user_name"]       => "C Person"
    ["release_count"]   => "50"
}

COMBINED ARRAYS USING USER_KEY AS THE NEW KEY

[1111]=>
   {
    ["user_name"]       => "A Person"
    ["release_count"]   => "5"
    ["taken_count"]     => "10"
  }
  [2222]=>
  {
    ["user_name"]       => "B Person"
    ["taken_count"]     => "20"
    ["release_count"]   => "0"
  }
   [3333]=>
  {
    ["user_name"]       => "C Person"
    ["taken_count"]     => "0"
    ["release_count"]   => "50"
  }

2 Answers 2

1

array_key_exists($key, $calls_taken_by_user) is not correct. This checks for the array index in the other array, but the two arrays don't have elements that correspond by index.

You should convert the second array into an associative array that's keyed by user_key. Then you can easily search for matching elements between the two arrays and merge them.

$assoc_calls_taken = [];
foreach ($calls_taken_by_user as $el) {
    $assoc_calls_taken[$el['user_id']] = $el;
}

foreach ($calls_released_by_user as $el) {
    $user = $el['user_key'];
    $all_user_calls_counts[$user] = $el;
    $all_user_calls_counts[$user]['release_count'] = isset($assoc_calls_take[$user])) ? $$assoc_calls_take[$user]['release_count']) : 0;
}
Sign up to request clarification or add additional context in comments.

1 Comment

You would have to also go through the calls_taken array to get all the users that appeared there but not in the calls_relased. Now in all_users_calls_counts you will only have users that appeared in the calls_released array.
0

Just iterate both arrays one after another:

$all_user_calls_counts = [];
foreach ($calls_taken_by_user as $taken) {
    $all_user_calls_counts[$taken['user_key']] = [
        'user_name'     => $taken['user_name'],
        'taken_count'   => $taken['taken_count'],
        'release_count' => '0'
    ];
}

foreach ($calls_released_by_user as $released) {
    $key = $released['user_key'];
    if (isset($all_user_calls_counts[$key])) {
        $all_user_calls_counts[$key]['release_count'] = $released['release_count'];
        continue;
    }
    $all_user_calls_counts[$key] = [
        'user_name'     => $released['user_name'],
        'taken_count'   => '0',
        'release_count' => $released['release_count']
    ];
}

You can make code more readable with array destructuring (assign fields to variables in one command), but I don't know which php version you use.

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.