59

In a piece of software, I merge two arrays with array_merge function. But I need to add the same array (with the same keys, of course) to an existing array.

The problem:

 $A = array('a' => 1, 'b' => 2, 'c' => 3);
 $B = array('c' => 4, 'd'=> 5);

 array_merge($A, $B);

 // result
 [a] => 1 [b] => 2 [c] => 4 [d] => 5

As you see, 'c' => 3 is missed.

So how can I merge all of them with the same keys?

kuzey beytar
  • 3,076
  • 6
  • 37
  • 46
  • 5
    array shoud have unique key...that is basic property of an array – xkeshav May 04 '11 at 09:41
  • 8
    How do you imagine an array with two keys that are the same? – Nemoden May 04 '11 at 09:44
  • Like they've said, keys must be unique. Consider using 2D arrays instead of associative, then you can merge them without any conflicts. i.e. array(array('a', 1), array('b', 2), array('c', 3), array('c', 4), array('d', 5)) – joelhardi May 04 '11 at 09:51
  • @Nemoden - yes, that's too strange. But my DB class need to merge WHERE, and PARAMS to binding in mysqli. Anyway, so I need to merge them :) – kuzey beytar May 04 '11 at 09:53
  • @kuzey this question does not have a [mcve] and this has led to the posting of answers that deliver different results. By clarifying your scenario via comment (instead of an [edit]), readers will have a difficult time understanding which kind of answer is appropriate. Your question still lacks an exact desired result. – mickmackusa May 15 '22 at 07:33
  • I agree with previous poster (@mickmackusa) that this question needs clarification. – Sybille Peters Jun 21 '23 at 13:10

6 Answers6

54

You need to use array_merge_recursive instead of array_merge. Of course there can only be one key equal to 'c' in the array, but the associated value will be an array containing both 3 and 4.

Lorien Brune
  • 830
  • 10
  • 16
Jon
  • 428,835
  • 81
  • 738
  • 806
  • 1
    Hm... strange... I've changes `array_merge` to `array_merge_recursive` and got the same results (array keys renumbered). On PHP.net site, under [array_merge](http://php.net/manual/en/function.array-merge.php), in Example #3 there's a comment: "_If you want to append array elements from the second array to the first array while not overwriting the elements from the first array and **not re-indexing**, use the + array union operator_". And that turned to be true in my case. Where did you read, that `array_merge_recursive` does not renumbers keys? – trejder Apr 18 '13 at 11:32
  • @trejder: There are no integer keys in this question, so re-indexing does not apply here. I answered with this in mind. – Jon Apr 18 '13 at 11:39
  • 2
    @jon the link you provide with the answer is broken. Could you inline the code please, if you still have it? – Adam Cameron Dec 07 '17 at 10:46
  • @AdamCameron use the code in the question, just with `array_merge_recursive` instead of the "plain" version. – Jon Dec 10 '17 at 20:06
  • @Elyor `array_merge` and `array_merge_recursive` are documented to have different behavior for string and integer keys, and for good reason: if they didn't, then the result of `array_merge([1], [2])` would be `[0 => 2]`, which is at least "unexpected". So they assume that if you have integer keys, then they don't really matter. If you have integer keys that matter then you must provide explicit logic that takes account of this. – Jon Oct 26 '20 at 09:02
43

Try with array_merge_recursive

$A = array('a' => 1, 'b' => 2, 'c' => 3);
$B = array('c' => 4, 'd'=> 5);
$c = array_merge_recursive($A,$B);

echo "<pre>";
print_r($c);
echo "</pre>";

will return

Array
(
    [a] => 1
    [b] => 2
    [c] => Array
        (
            [0] => 3
            [1] => 4
        )

    [d] => 5
)
StefansArya
  • 2,802
  • 3
  • 24
  • 25
xkeshav
  • 53,360
  • 44
  • 177
  • 245
7
$arr1 = array(
   "0" => array("fid" => 1, "tid" => 1, "name" => "Melon"),
   "1" => array("fid" => 1, "tid" => 4, "name" => "Tansuozhe"),
   "2" => array("fid" => 1, "tid" => 6, "name" => "Chao"),
   "3" => array("fid" => 1, "tid" => 7, "name" => "Xi"),
   "4" => array("fid" => 2, "tid" => 9, "name" => "Xigua")
);

if you want to convert this array as following:

$arr2 = array(
   "0" => array(
          "0" => array("fid" => 1, "tid" => 1, "name" => "Melon"),
          "1" => array("fid" => 1, "tid" => 4, "name" => "Tansuozhe"),
          "2" => array("fid" => 1, "tid" => 6, "name" => "Chao"),
          "3" => array("fid" => 1, "tid" => 7, "name" => "Xi")
    ),

    "1" => array(
          "0" =>array("fid" => 2, "tid" => 9, "name" => "Xigua")
     )
);

so, my answer will be like this:

$outer_array = array();
$unique_array = array();
foreach($arr1 as $key => $value)
{
    $inner_array = array();

    $fid_value = $value['fid'];
    if(!in_array($value['fid'], $unique_array))
    {
            array_push($unique_array, $fid_value);
            unset($value['fid']);
            array_push($inner_array, $value);
            $outer_array[$fid_value] = $inner_array;


    }else{
            unset($value['fid']);
            array_push($outer_array[$fid_value], $value);

    }
}
var_dump(array_values($outer_array));

hope this answer will help somebody sometime.

Raza
  • 3,147
  • 2
  • 31
  • 35
Melon
  • 71
  • 1
  • 1
3

I just wrote this function, it should do the trick for you, but it does left join

public function mergePerKey($array1,$array2)
    {
        $mergedArray = [];

        foreach ($array1 as $key => $value) 
        {
            if(isset($array2[$key]))
             {
               $mergedArray[$value] = null;

               continue;
             }
            $mergedArray[$value] = $array2[$key];
        }

        return $mergedArray;
    }
TheodorosPloumis
  • 2,396
  • 1
  • 17
  • 31
Kamaro
  • 955
  • 1
  • 10
  • 11
  • 2
    Please explain your snippet and include a working demo link. – mickmackusa May 14 '22 at 05:06
  • 1
    I second suggestion for explaining the code snippet. But I don't think a working demo link is absolutely necessary here. (in addition to this - how can answers be useful when OP didn't bother to update question to make it more clear (besides polite comments requesting to do so) - it is not really clear what is the intended result in this question). – Sybille Peters Jun 21 '23 at 13:14
3
 $A = array('a' => 1, 'b' => 2, 'c' => 3);
 $B = array('c' => 4, 'd'=> 5);
 $C = array_merge_recursive($A, $B);
 $aWhere = array();
 foreach ($C as $k=>$v) {

    if (is_array($v)) {
        $aWhere[] = $k . ' in ('.implode(', ',$v).')';
    }
    else {
        $aWhere[] = $k . ' = ' . $v;
    }
 }
 $where = implode(' AND ', $aWhere);
 echo $where;
Nemoden
  • 8,816
  • 6
  • 41
  • 65
  • Has this answer deviated from the asked question? Why am I seeing "where" and "in ()`? – mickmackusa May 14 '22 at 05:08
  • @mickmackusa some of the comments to the original question indicate the question WAS something to do with where statements. I'd assume the question has been redacted. Even despite this my answer is still in sync the the question since it does include the feasible solution of using `array_merge_recursive` – Nemoden May 15 '22 at 07:05
  • Ah I see the comment that your answer caters to. This answer is missing its educational explanation. Explaining in a comment, that this answer is not implementing secure querying practices, is not ideal. I didn't read the comment before reading your answer. – mickmackusa May 15 '22 at 07:41
-1

Two entries in an array can't share a key, you'll need to change the key for the duplicate

Mild Fuzz
  • 29,463
  • 31
  • 100
  • 148
  • Expressing that the question is Unclear can be done as a comment under the question or by voting to close as Need Clarity. – mickmackusa May 15 '22 at 07:39