how do I concatenate the string values of two arrays pairwise with PHP?
So I have two arrays
Array
(
[0] => test
[1] => test 1
[2] => test 2
[3] => test 3
)
and
Ar开发者_运维问答ray
(
[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
You could do it with array_map
:
$combined = array_map(function($a, $b) { return $a . ' ' . $b; }, $a1, $a2));
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);
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.
you can do it like
for($i; $i<count($a); $i++)
{
$arr[$i] = $a[$i]." ".$b[$i];
}
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]);
}
Assuming the two arrays are $array1 and $array2
for($x = 0; $x < count($array2); $x++){
$array1[$x] = $array1[$x] . ' ' . $array2[$x];
}
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....
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.
you loop through it to create a new array. There's no built-in function. Welcome to the wonderful world of programming :)
Hints:
- http://pt2.php.net/manual/en/control-structures.foreach.php
- You can combine two strings with "."
精彩评论