Как объединить строковые значения двух массивов попарно с PHP? - PullRequest
4 голосов
/ 19 сентября 2011

Итак, у меня есть два массива

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

и

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

Я хочу объединить их вместе, чтобы получить такой массив?

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

Я обнаружил множество функций, таких как array_merge и array_combine, но ничего такого, что я хочу делать.

Есть идеи?

Заранее спасибо.

Макс

Ответы [ 9 ]

4 голосов
/ 19 сентября 2011

Вы можете сделать это с array_map:

$combined = array_map(function($a, $b) { return $a . ' ' . $b; }, $a1, $a2));
1 голос
/ 19 сентября 2011

Вот решение с одной строкой, если вы используете Php 5.3.0 +:

$result = array_map(function ($x, $y) { return $x.$y; }, $array1, $array2);
0 голосов
/ 31 января 2019

Многие ответы рекомендуют способ array_map, а многие более тривиальный for цикл.

Я думаю, что решение array_map выглядит лучше и «более продвинуто», чем циклическое выполнение массивов и построениеконкатенированный массив в цикле for, НО - вопреки моим ожиданиям - он намного медленнее обычного for.

Я провел несколько тестов с версией PHP 7.1.23-4 на Ubuntu16.04.1: с двумя массивами, каждый из которых содержит 250 тыс. Элементов 10-значных случайных чисел, решение for заняло 4,7004 с в течение 20 прогонов, в то время как решение array_map заняло 11,7939 с в течение 20 прогонов на моей машине, почти в 2,5 раза медленнее !!!

Я бы ожидал, что PHP лучше оптимизирует встроенную функцию array_map, чем цикл for, но выглядит наоборот:

Код, который я тестировал:

// 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";

Возникает вопрос, чем хороша array_map?Один из возможных ответов, который приходит мне в голову, заключается в том, что если у нас где-то есть предопределенная функция, может быть, в сторонней библиотеке, мы хотели бы применить ее к массивам, и мы не хотим переопределять эту функцию внутри нашего цикла for.array_map в этом случае представляется удобным применить эту функцию к нашим массивам.Но разве это лучше, чем вызывать функцию из цикла for?

Я тоже это проверял, и похоже, что array_map превосходит при использовании предопределенных функций.На этот раз array_map заняло 8,7176 с, а цикл for занял 12,8452 с, чтобы выполнить ту же работу, что и выше.

Код, который я тестировал:

// 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";

Очень длинная историякороче, общий вывод:

  • Вызов предопределенной функции: используйте array_map, это занимает ~ 40% меньше времени (8,7 с против 12,8 с)
  • Реализация массива прямо там, где это необходимо: используйте цикл for, это займет ~ 60% меньше времени (4,7 с против 11,8 с).
  • У вас есть выбор между использованием предопределенной функции или (повторно) реализовать его там, где это необходимо: использовать цикл for и выполнить необходимые манипуляции внутри цикла, это займет ~ 45% меньше времени (4,7 с против 8,7 с).

На основании этого, в вашем конкретном сценарии использования , используйте цикл for и выполните конкатенацию внутри тела цикла, не вызывая другие функции.

0 голосов
/ 28 июня 2013

Если у вас есть данные, поступающие из двух разных запросов, и они становятся двумя разными массивами, объединение их не всегда является ответом.

Там, когда они помещены в массив ([]), они могут быть зациклены с помощью foreach для подсчета их количества, а затем зациклены вместе.

Примечание: они должны иметь одинаковое количество в каждом массиве, или один может закончиться раньше, чем другой ... ..

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>";
}

Затем отобразится: -

Tescos - 78
Асда - 89
Моррисонс - 23
Sainsburys - 46

Вы можете даже добавить счетное число, чтобы показать этот номер элемента списка ...

0 голосов
/ 19 сентября 2011

Предполагая, что двумя массивами являются $ array1 и $ array2

for($x = 0; $x < count($array2); $x++){
        $array1[$x] = $array1[$x] . ' ' . $array2[$x];
    }
0 голосов
/ 19 сентября 2011

Просто выполните цикл и присвойте объединение новому массиву:

$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]);
}
0 голосов
/ 19 сентября 2011

вы можете сделать это как

for($i; $i<count($a); $i++)
{
    $arr[$i] = $a[$i]." ".$b[$i];
}
0 голосов
/ 19 сентября 2011

Нет встроенной функции (о которой я знаю), чтобы выполнить это. Используйте цикл:

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

Адаптируйте цикл по своему вкусу: объедините только минимальное количество элементов, объедините пустую строку, если один из массивов короче и т. Д.

0 голосов
/ 19 сентября 2011

вы перебираете его, чтобы создать новый массив. Там нет встроенной функции. Добро пожаловать в удивительный мир программирования:)

Советы:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...