+ оператор для массива в PHP?


197
$test = array('hi');
$test += array('test','oh');
var_dump($test);

Что +означает массив в PHP?


5
Я заметил, что у вашего вопроса был +=и принятый ответ +. Судя по моему тестированию, они ведут себя одинаково.
user151841

7
Документации подводит итог довольно хорошо
artfulrobot


@RobbieAverill - это вопрос, к которому относится этот справочный вопрос. Так что, во всяком случае, этот справочный вопрос является дубликатом
icc97

2
Кто-нибудь еще немного напуган тем, что такая фундаментальная вещь, как конкатенация массивов, должна быть выполнена array_merge? Это как если бы массивы по умолчанию были ассоциативными массивами, а числовые массивы - гражданами второго сорта.
icc97

Ответы:


277

Цитата из руководства PHP по операторам языка

Оператор + возвращает правый массив, добавленный к левому массиву; для ключей, которые существуют в обоих массивах, будут использоваться элементы из левого массива, а соответствующие элементы из правого массива будут проигнорированы.

Итак, если вы это сделаете

$array1 = ['one',   'two',          'foo' => 'bar'];
$array2 = ['three', 'four', 'five', 'foo' => 'baz']; 

print_r($array1 + $array2);

Ты получишь

Array
(
    [0] => one   // preserved from $array1 (left-hand array)
    [1] => two   // preserved from $array1 (left-hand array)
    [foo] => bar // preserved from $array1 (left-hand array)
    [2] => five  // added from $array2 (right-hand array)
)

Таким образом, логика +эквивалентна следующему фрагменту:

$union = $array1;

foreach ($array2 as $key => $value) {
    if (false === array_key_exists($key, $union)) {
        $union[$key] = $value;
    }
}

Если вас интересуют подробности реализации C-уровня, обратитесь к


Обратите внимание, что +это отличается от того, как array_merge()объединить массивы:

print_r(array_merge($array1, $array2));

дал бы вам

Array
(
    [0] => one   // preserved from $array1
    [1] => two   // preserved from $array1
    [foo] => baz // overwritten from $array2
    [2] => three // appended from $array2
    [3] => four  // appended from $array2
    [4] => five  // appended from $array2
)

Дополнительные примеры см. На связанных страницах.


1
@Pacerier PHP, созданный php.net, не имеет формальной спецификации, но оба вызова +и находятся под капотом. Это также ожидается, поскольку в PHP массивы реализованы в виде упорядоченных хэш-карт. array_mergezend_hash_merge
епископ

1
@Pacerier Онлайн-документы php.net - это самая близкая запись к спецификации, но IMO эти документы не соответствуют истинной спецификации: во-первых, они обновляются после написания кода; во-вторых, они написаны не для каждого специального использования.
епископ

16
Поведение PHP +и array_mergeявляется извращенным и неинтуитивным. Они противоположны тому, что при чтении на простом английском языке интуитивно подсказывает вам «добавление» или «слияние» массивов. Другие языки / библиотеки используются +для объединения списков (например, в Python) и функций «слияния» для добавления пар ключ / значение из одного объекта в другой (например, в lodash). Однако в PHP все наоборот; array_mergeможет использоваться для объединения массивов, подобных списку, но +не может. В отличие от array_merge, +всегда выполняет операцию, которую на любом другом языке назвали бы «слиянием».
Марк Эмери,

1
@ icc97, это действительно только HashMaps. См. Nikic.github.io/2014/12/22/…
Гордон

2
Я попытался подав ошибку , чтобы увидеть , если псевдоним array_concatможет быть создан array_merge.
icc97

19

Лучший пример, который я нашел для этого, - это массив конфигурации.

$user_vars = array("username"=>"John Doe");
$default_vars = array("username"=>"Unknown", "email"=>"no-reply@domain.com");

$config = $user_vars + $default_vars;

Как $default_varsпредполагается, это массив значений по умолчанию. $user_varsМассив будет перезаписать значения , определенные в $default_vars. Любые отсутствующие значения в $user_varsтеперь являются значениями по умолчанию $default_vars.

Это было бы print_rтак:

Array(2){
    "username" => "John Doe",
    "email" => "no-reply@domain.com"
}

Надеюсь, это поможет!


6

Этот оператор принимает объединение двух массивов (то же, что и array_merge, за исключением того, что с array_merge дублирующиеся ключи перезаписываются).

Документацию по операторам массива можно найти здесь .


1
Предупреждение для новичков: результат операции равен нулю, если какой-либо из массивов равен нулю . Некоторые могут не заботиться об этом, предполагая, что, поскольку это операция объединения, результатом будет правильный (не нулевой) массив, если один из них имеет значение NULL. Но это верно, если один из массивов является пустым .
Sandeepan Nath

Поэтому я считаю хорошей практикой инициализировать входные массивы как пустые. Что вы скажете, ребята?
Sandeepan Nath

5

Осторожно обращайтесь с цифровыми клавишами, если их нужно сохранить или вы ничего не хотите потерять

$a = array(2 => "a2", 4 => "a4", 5 => "a5");
$b = array(1 => "b1", 3 => "b3", 4 => "b4");

союз

print_r($a+$b);
Array
(
    [2] => a2
    [4] => a4
    [5] => a5
    [1] => b1
    [3] => b3
)

слияние

print_r(array_merge($a, $b));
Array
(
    [0] => a2
    [1] => a4
    [2] => a5
    [3] => b1
    [4] => b3
    [5] => b4
)

3

+Оператор производит одни и те же результаты , как array_replace () . Однако, поскольку аргументы оператора меняются местами, порядок результирующего массива также может быть другим.

Расширяя еще один пример с этой страницы:

$array1 = array('one', 'two', 'foo' => 'bar');
$array2 = array('three', 'four', 'five', 'foo' => 'baz'); 

print_r($array1 + $array2);
print_r(array_replace($array2, $array1)); //note reversed argument order

выходы:

Array
(
    [0] => one   // preserved from $array1
    [1] => two   // preserved from $array1
    [foo] => bar // preserved from $array1
    [2] => five  // added from $array2
)
Array
(
    [0] => one   // preserved from $array1
    [1] => two   // preserved from $array1
    [2] => five  // added from $array2
    [foo] => bar // preserved from $array1
)

+Гарантирован ли порядок спецификациями? О чем array_replace?
Pacerier

1
  1. Операция «Массив плюс» обрабатывает весь массив как связанный массив.
  2. При конфликте клавиш во время плюса, левое (предыдущее) значение будет сохранено

Я размещаю код ниже, чтобы прояснить ситуацию.

$a + $b = array_plus($a, $b)

function array_plus($a, $b){
    $results = array();
    foreach($a as $k=>$v) if(!isset($results[$k]))$results[$k] = $v;
    foreach($b as $k=>$v) if(!isset($results[$k]))$results[$k] = $v;
    return $results;
}

Выполнение кода @ Tamlyn, кажется, доказывает, что ваше утверждение "массив плюс операция обрабатывает весь массив как ассоциативный массив" неверно.
Pacerier

@Pacerier, этот ключ также может быть целым числом.
Hitesh


-4
$var1 = "example";
$var2 = "test";
$output = array_merge((array)$var1,(array)$var2);
print_r($output);

Массив ([0] => пример [1] => тест)


1
В этом потоке несколько раз упоминается, что array_merge () НЕ конгруэнтно.
doublejosh

@doublejosh, "конгруэнтный"? Имея в виду?
Pacerier

1
Они не то же самое.
doublejosh
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.