2

Hello & thanks for your interest

I do have two arrays:

  1. [A] -from the mysql query of one database on server1- the $postings_array - a SELECT of all postings of a discussion-thread (based on the thread's id)
  2. [B] -from the mysql query of an other database on server2 - the $usersdata_array - a SELECT of all postings of a discussion-thread (based on the thread's id)

This means:

  • in [A] there are many postings-sub-arrays and in [B] one or more userdata-sub-arrays.
  • both arrays always do include a key named usrsID in each of their subarrays.
I need to extend the Sub-Arrays in $postings_array [A]

by merging them 

with the Sub-Arrays of the $usersdata_array [B]

based on WHERE the VALUE of the usrsID KEY in the sub-array[A] is EQUAL to the usrsID KEY in the sub-array[B].

EXAMPLE:

Array [A]:
(
    [0] => Array
        (
            [ID] => 5
            [usrsID] => 3
            [tid] => 19
            [txtid] => 22
        )
    [1] => Array
        (
            [ID] => 6
            [usrsID] => 1
            [tid] => 19
            [txtid] => 23
        )
    [2] => Array
        (
            [ID] => 7
            [usrsID] => 2
            [tid] => 19
            [txtid] => 24
        )
    [3] => Array
        (
            [ID] => 8
            [usrsID] => 1
            [tid] => 19
            [txtid] => 25
        )
)

--

Array [B]:
(
    [0] => Array
        (
            [id] => 1
            [usrsID] => 1
            [avatarID] => 1

        )
    [1] => Array
        (
            [id] => 2
            [usrsID] => 2
            [avatarID] => 3

        )
    [2] => Array
        (
            [id] => 3
            [usrsID] => 3
            [avatarID] => 22

        )

)

needed result (the by [B] extended [A] for the example above):

Array [A_extended]:
(
    [0] => Array
        (
            [ID] => 5
            [usrsID] => 3
            [tid] => 19
            [txtid] => 22
            [id] => 3
            [avatarID] => 22
        )
    [1] => Array
        (
            [ID] => 6
            [usrsID] => 1
            [tid] => 19
            [txtid] => 23
            [id] => 1
            [avatarID] => 1
        )
    [2] => Array
        (
            [ID] => 7
            [usrsID] => 2
            [tid] => 19
            [txtid] => 24
            [id] => 2
            [avatarID] => 3
        )
    [3] => Array
        (
            [ID] => 8
            [usrsID] => 1
            [tid] => 19
            [txtid] => 25
            [id] => 1
            [avatarID] => 1
        )
)

... I think, it's a common problem so there should be a best-practice around (may be in one inbuild php function or a combination of two or three of them) - and I do not have to reinvent the wheel. At least, I hope so...

else, my approach would be

  1. check the amounts of iterations (= the subarrays found in the $usersdata_array [B] )
  2. iterate over the outerHaystack and trigger a function when $needle was found in innerHaystack
  3. perform merge via checkSubArrayfunc

Approach, with hayStackArray = complete [A]Array; needle = $usrsID value of [B] Sub-Array:

function checkSubArrayfunc($hayStackSubArray, $needle, $toMergeSubArray) {

        if (in_array(array('$hayStackSubArray'), $needle)) {
                array_merge_recursive($hayStackSubArray, $toMergeSubArray);
        }
    }

flowfab
  • 99
  • 11
  • Does your supplied code work? – bestprogrammerintheworld Apr 23 '20 at 17:05
  • @bestprogrammerintheworld I am not quite sure whch code you mean: the checkSubArrayfunc() was only a scetched idea - but, as mentioned already: there are likely best-practices around because my requirement ("merging sub-arrays where certain values of certain keys are the same" should be a very common question). If you did mean the rest (queries from databases with some joins and a SELECT WHERE ~ id IN implode array_map intval $sel_sub_array... : YES: I have the arrays of same design & depth at hand -all I need is to merge all sub-arrays based on a rule -so that the posts do have the user-data – flowfab Apr 23 '20 at 21:07
  • Related from 2012: [Array merge on key of two associative arrays in php?](https://stackoverflow.com/questions/9112920/array-merge-on-key-of-two-associative-arrays-in-php) – mickmackusa Aug 21 '22 at 06:41

3 Answers3

0

At first take an empty array for store marged array. then traversed in both array. if the userID are be same in both the array of element then marge these array and push in margeArr.

$margeArr = [];
foreach($Array_A as $a){
  foreach($Array_B as $b){
    if($a['usrsID'] == $b['usrsID']){
      array_push($margeArr,array_merge($a,$b));
    }
  }
}
print_r($margeArr);

Comment by the questionaire: It's a great solution - it really meets the requirements described in my question and merges the to be marged Array with the key-value-pairs of the "to be injected"-Array. But I prefere the bestprogrammersinintheworld's solution, where I can rename the keys "en passant / on-the-fly":

foreach($arr_b as $b_item) {
    foreach($arr_a as $key => &$a_item) {
        if ($b_item['usrsID'] == $a_item['usrsID']) {
            $a_item['myNewKeyName1'] = $b_item['usrsID'];
            $a_item['myNewKeyName2'] = $b_item['avatarID'];
        }
    }
}
print("<pre>".print_r($arr_a,true)."</pre>"); 
flowfab
  • 99
  • 11
Anik Anwar
  • 625
  • 5
  • 11
  • It's a great solution - it really meets the requirements described in my question and merges the to be marged Array with the key-value-pairs of the "to be injected"-Array. But I prefere the bestprogrammersinintheworld's solution, where I can rename the keys "en passant / on-the-fly".. – flowfab Apr 25 '20 at 09:06
0

Try this:

foreach($arr_b as $b_item) {
    foreach($arr_a as $key => &$a_item) {
        if ($b_item['usrsID'] == $a_item['usrsID']) {
            $a_item['id'] = $b_item['usrsID'];
            $a_item['avatarID'] = $b_item['avatarID'];
        }
    }
}

Your output of $_arr_a will be:

Array
(
    [0] => Array
        (
            [ID] => 5
            [usrsID] => 3
            [tid] => 19
            [txtid] => 22
            [id] => 3
            [avatarID] => 22
        )

    [1] => Array
        (
            [ID] => 6
            [usrsID] => 1
            [tid] => 19
            [txtid] => 23
            [id] => 1
            [avatarID] => 1
        )

    [2] => Array
        (
            [ID] => 7
            [usrsID] => 2
            [tid] => 19
            [txtid] => 24
            [id] => 2
            [avatarID] => 3
        )

    [3] => Array
        (
            [ID] => 8
            [usrsID] => 1
            [tid] => 19
            [txtid] => 25
            [id] => 1
            [avatarID] => 1
        )

)
bestprogrammerintheworld
  • 5,417
  • 7
  • 43
  • 72
0

Sorting my advice from best to worst...

  1. Joining this data should be done before PHP is necessary. Depending on the location of the two sources, this may be trivial, but JOINing via SQL is the best, most direct, most professional option. These links may be helpful:

  2. In lieu of option 1, declare and leverage a lookup array (in PHP) which would have the identifying column as its first level keys. Then you don't need to nest another loop to relate the two data sets.

    $lookup = array_column($arrayB, null, 'usrsID');
    foreach ($arrayA as $row) {
        $result[] = $row + ($lookup[$row['usrsID']] ?? []);
    }
    
  3. The worst option which I do NOT recommend is writing a nested loop with a condition inside of it. All previous answers are doing this -- and slowing down an already inefficient approach, they don't even break inside the condition block.

mickmackusa
  • 43,625
  • 12
  • 83
  • 136