6

So I have two arrays

Array
(
[0] => test
[1] => test 1
[2] => test 2
[3] => test 3
)

and

Array
(
[0] => test
[1] => test 1
[2] => test 2
[3] => test 3
)

I want to combine them together so I get an array like this?

Array
(
[0] => test test
[1] => test 1 test 1
[2] => test 2 test 2
[3] => test 3 test 3
)

I have found lots of functions like array_merge and array_combine but nothing that does what I want to do.

Any ideas?

Thanks in advance.

Max

3
  • yes I am, I wanted to know if there was a function that did it for me ^_^ Commented Sep 19, 2011 at 16:05
  • 3
    Given there are built-in functions for many things in PHP, I don't think it's an unreasonable question to ask. Commented Sep 19, 2011 at 16:11
  • one can easily browse them, without asking others to do it for him Commented Sep 19, 2011 at 16:25

9 Answers 9

6

You could do it with array_map:

$combined = array_map(function($a, $b) { return $a . ' ' . $b; }, $a1, $a2));
Sign up to request clarification or add additional context in comments.

2 Comments

This is an elegant solution, however it has inferior performance over a for loop, or even calling a predefined named function by array_map. See my answer below for comparison. Looks like it's never a good idea to apply array_map on an anonymous function. Can be up to 2.5x slower, than a simple for loop. Probably because the anonymous function is re-instantiated for each element by the engine, or who knows why...
In most real world use cases, the performance difference between the two solutions is neglibile. Both solutions are fine — use whichever one you find makes the code more readable. Chances are slim that array_map usage is an issue in real code. If benchmarking reveals that it is, then switch to the for solution, but in general you should avoid micro-optimizations like this and optimize for readability.
2

Here is a one line solution if you are using Php 5.3.0+:

$result = array_map(function ($x, $y) { return $x.$y; }, $array1, $array2);

Comments

1

Many answers recommend the array_map way, and many the more trivial for loop way.

I think the array_map solution looks nicer and "more advanced" than looping over the arrays and building the concatenated array in a for loop, BUT - contrary to my expectations - it is much slower than a regular for.

I've run some tests with PHP Version 7.1.23-4 on ubuntu 16.04.1: with two arrays each containing 250k elements of 10 digit random numbers a for solution took 4.7004 sec for 20 runs, while the array_map solution took 11.7939 sec for 20 runs on my machine, almost 2.5 times slower!!!

I would have expected PHP to better optimise the built in array_map feature, than a for loop, but looks like the opposite.

The code I've tested:

// Init the test

$total_time_for = 0;
$total_time_arraymap = 0;

$array1 = [];
$array2 = [];
for ( $i = 1; $i < 250000; $i ++ ) {
    $array1[] = mt_rand(1000000000,9999999999);
    $array2[] = mt_rand(1000000000,9999999999);
}

// Init completed

for ( $j = 1; $j <= 20; $j ++ ) {
    
    // Init for method
    $array_new = [];
    
    $startTime = microtime(true);
    
    // Test for method
    for ( $i = 0; $i < count($array1); $i ++ ) {
        $array_new[] = $array1[$i] . " " . $array2[$i];
    }
    // End of test content
    
    $endTime = microtime(true);
    $elapsed = $endTime - $startTime;
    $total_time_for += $elapsed;
    //echo "for - Execution time : $elapsed seconds" . "\n";
    
    unset($array_new);
    
    //----
    
    // Init array_map method
    
    $array_new = [];
    
    $startTime = microtime(true);
    
    // Test array_map method
    $array_new = array_map(function($a, $b) { return $a . ' ' . $b; }, $array1, $array2);
    // End of test content
    
    $endTime = microtime(true);
    $elapsed = $endTime - $startTime;
    $total_time_arraymap += $elapsed;
    //echo "array_map - Execution time : $elapsed seconds" . "\n";
    
    unset($array_new);
}

echo "for - Total execution time : $total_time_for seconds" . "\n";
echo "array_map - Total execution time : $total_time_arraymap seconds" . "\n";

Question arises than what array_map is good for? One possible answer that comes into my mind, is what if we have a predefined function somewhere, maybe in a 3rd party library, we'd like to apply to the arrays and we don't want to reimplement that function inside our for loop. array_map seems to be convenient in that case, to apply that function on our arrays. But is it any better, than calling the function from a for loop?

I've tested this as well, and looks like truly, array_map excels when using predefined functions. This time array_map took 8.7176 sec, while for loop took 12.8452 sec to do the same job as above.

The code I've tested:

// Init the test

$total_time_for = 0;
$total_time_arraymap = 0;

$array1 = [];
$array2 = [];
for ( $i = 1; $i <= 250000; $i ++ ) {
    $array1[] = mt_rand(1000000000,9999999999);
    $array2[] = mt_rand(1000000000,9999999999);
}

function combine($a, $b) {
    return $a . ' ' . $b;
}

// Init completed

for ( $j = 1; $j <= 20; $j ++ ) {
    
    // Init for method
    $array_new = [];
    
    $startTime = microtime(true);
    
    // Test for method
    for ( $i = 0; $i < count($array1); $i ++ ) {
        $array_new[] = combine($array1[$i], $array2[$i]);
    }
    // End of test content
    
    $endTime = microtime(true);
    $elapsed = $endTime - $startTime;
    $total_time_for += $elapsed;
    //echo "for external function call - Execution time : $elapsed seconds" . "\n";
    
    unset($array_new);
    
    //----
    
    // Init array_map method
    
    $array_new = [];
    
    $startTime = microtime(true);
    
    // Test array_map method
    $array_new = array_map('combine', $array1, $array2);
    // End of test content
    
    $endTime = microtime(true);
    $elapsed = $endTime - $startTime;
    $total_time_arraymap += $elapsed;
    //echo "array_map external function call - Execution time : $elapsed seconds" . "\n";
    
    unset($array_new);
}

echo "for external function call - Total execution time : $total_time_for seconds" . "\n";
echo "array_map external function call - Total execution time : $total_time_arraymap seconds" . "\n";

So long story short, the general conclusion:

  • Calling a predefined function: use array_map, it takes ~40% less time (8.7 sec vs. 12.8 sec )
  • Implementing the array manipulation right where needed: use for loop, it takes ~60% less time (4.7 sec vs. 11.8 sec).
  • Have a choice between using a predefined function or (re-)implementing it right where needed: use for loop and implement the required manipulations inside the loop, it takes ~45% less time ( 4.7 sec vs. 8.7 sec. ).

Based on this, in your particular use-case, use for loop and do the concatenation inside the loop body, without calling other functions.

1 Comment

there is a bug in your code: Warning: Undefined array key 250000. It should be for ($i = 0; $i < count($array1); $i++) { instead of for ($i = 0; $i <= count($array1); $i++) {
0

you can do it like

for($i; $i<count($a); $i++)
{
    $arr[$i] = $a[$i]." ".$b[$i];
}

Comments

0

Just loop through and assign the concatenation to a new array:

$array1=array("test","test 1","test 2","test 3");
$array2=array("x","y","z","w");

$new_array=array();

foreach (range(0,count($array1)-1) as $i)
{
  array_push($new_array,$array1[$i] . $array2[$i]);
}

Comments

0

Assuming the two arrays are $array1 and $array2

for($x = 0; $x < count($array2); $x++){
        $array1[$x] = $array1[$x] . ' ' . $array2[$x];
    }

Comments

0

If you have data coming from two different querys and they become two different arrays, combining them is not always an answer.

There for when placed into an array ([]) they can be looped with a foreach to count how many, then looped together.

Note: they must have the same amount in each array or one may finish before the other…..

foreach ($monthlytarget as $value) {
// find how many results there were
   $loopnumber++;
}

echo $loopnumber;

for ($i = 0; $i < $loopnumber; $i++) {
echo $shop[$i];
echo " - ";
echo $monthlytarget[$i];
echo "<br>";
}

This will then display: -

Tescos - 78
Asda - 89
Morrisons - 23
Sainsburys - 46

You can even add in the count number to show this list item number....

Comments

0

There's no built-in function (that I know of) to accomplish that. Use a loop:

$combined = array();
for($i = 0, $l = min(count($a1), count($a2)); $i < $l; ++$i) {
  $combined[$i] = $a1[$i] . $a2[$i];
}

Adapt the loop to your liking: only concatenate the minimum number of elements, concatenate empty string if one of the arrays is shorter, etc.

Comments

-1

you loop through it to create a new array. There's no built-in function. Welcome to the wonderful world of programming :)

Hints:

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.