Поєднайте два масиви


88

У мене є два таких масиви:

array( 
'11' => '11',
'22' => '22',
'33' => '33',
'44' => '44'
);

array( 
'44' => '44',
'55' => '55',
'66' => '66',
'77' => '77'
);

Я хочу поєднати ці два масиви таким чином, щоб він не містив дублікатів, а також зберегти їх оригінальні ключі. Наприклад, результат повинен бути:

array( 
'11' => '11',
'22' => '22',
'33' => '33',
'44' => '44',
'55' => '55',
'66' => '66',
'77' => '77'
);

Я спробував це, але це змінює їхні початкові ключі:

$output = array_unique( array_merge( $array1 , $array2 ) );

Будь-яке рішення?

Відповіді:


161

Просто використовуйте:

$output = array_merge($array1, $array2);

Це має вирішити це. Оскільки ви використовуєте рядкові ключі, якщо одна клавіша зустрічається більше одного разу (як '44'у вашому прикладі), одна клавіша замінить наступні з тим самим іменем. Оскільки у вашому випадку вони обидва мають однакове значення, так чи інакше, це не має значення, і це також видалить копії.

Оновлення: Я щойно зрозумів, що PHP обробляє числові рядкові ключі як числа (цілі числа), і тому буде поводитися так, що означає, що він також перенумерує ключі ...

Обхідний шлях полягає у відтворенні ключів.

$output = array_combine($output, $output);

Оновлення 2: Я завжди забуваю, що існує також оператор (напівжирним шрифтом, бо це справді те, що ви шукаєте!: D)

$output = $array1 + $array2;

Все це можна побачити за адресою : http://php.net/manual/en/function.array-merge.php


5
@KingCrunch - Навіть якщо цифри вказані в лапках, це не строкові ключі, тому індекс не буде збережений. Приклад: ideone.com/I2NFT
Брендан Буллен

1
Справді ... Спочатку я хотів поговорити про "помилку", але потім я помітив, що в посібнику йдеться лише про "числові клавіші", а не про "цілочисельні клавіші". Відчуває себе трохи заплутаним.
KingCrunch

+1 Я забув про оператора! Відмінно (поставте цю частину жирним шрифтом
!;

3
Так $array1 + $array2само коротке та ефективне рішення замість array_merge() - array_combine()комбінації
Awan

2
УВАГА! для масивів, що не є $a + $b != array_merge($a, $b)
асоційованими,

33

Ви повинні врахувати це $array1 + $array2 != $array2 + $array1

$array1 = array(
'11' => 'x1',
'22' => 'x1' 
);  

$array2 = array(
'22' => 'x2',
'33' => 'x2' 
);

з $ array1 + $ array2

$array1 + $array2 = array(
'11' => 'x1',
'22' => 'x1',
'33' => 'x2'
);

і з $ array2 + $ array1

$array2 + $array1 = array(  
'11' => 'x1',  
'22' => 'x2',  
'33' => 'x2'  
);

25

Це працює:

$output = $array1 + $array2;

12
Я б не рекомендував цього, оскільки це дуже неінтуїтивно, наприклад[1,2,3] + [4,5,6] == [1,2,3]
jchook

@jchook Що ви тоді рекомендуєте?
Michas

Це те, що мені потрібно було, дякую. Ось чому: http_build_query(array_merge($array1, $array2))не працював у мене, тоді як http_build_query($array1 + $array2)працював.
BarryMode

4

Для цього ви можете прокрутити один і додати до іншого:

<?php

$test1 = array( 
'11' => '11',
'22' => '22',
'33' => '33',
'44' => '44'
);

$test2 = array( 
'44' => '44',
'55' => '55',
'66' => '66',
'77' => '77'
);


function combineWithKeys($array1, $array2)
{
    foreach($array1 as $key=>$value) $array2[$key] = $value;
    asort($array2);
    return $array2;
} 

print_r(combineWithKeys($test1, $test2));

?>

ОНОВЛЕННЯ: KingCrunch запропонував найкраще рішення :print_r($array1+$array2);


2

Якщо ви використовуєте PHP 7.4 або новішу версію, ви можете використовувати оператор поширення ...як такі приклади з Документів PHP:

$arr1 = [1, 2, 3];
$arr2 = [...$arr1]; //[1, 2, 3]
$arr3 = [0, ...$arr1]; //[0, 1, 2, 3]
$arr4 = array(...$arr1, ...$arr2, 111); //[1, 2, 3, 1, 2, 3, 111]
$arr5 = [...$arr1, ...$arr1]; //[1, 2, 3, 1, 2, 3]

function getArr() {
  return ['a', 'b'];
}
$arr6 = [...getArr(), 'c']; //['a', 'b', 'c']

$arr7 = [...new ArrayIterator(['a', 'b', 'c'])]; //['a', 'b', 'c']

function arrGen() {
    for($i = 11; $i < 15; $i++) {
        yield $i;
    }
}
$arr8 = [...arrGen()]; //[11, 12, 13, 14]

Це працює як у JavaScript ES6.

Докладніше див . На https://wiki.php.net/rfc/spread_operator_for_array .


Це не стосується питання. OP має рядкові ключі для масиву (це не працює з оператором поширення), і OP хоче зберегти ключі (оператор поширення викидає ключі). Крім того, OP не хоче дублікатів.
martti

О, я бачу ваші думки. Це правда, і ти маєш рацію. Чи можете ви надати код, який допоможе нам покращити мою відповідь для інших людей? Буду вдячний за ваш час! Щиро дякую, що вказали на недоліки моєї відповіді.
Студент наук

Я не думаю, що оператор поширення - це шлях сюди. Натомість використовуйте $array1 + $array2
подану

Я цього не знав! Я маю на увазі, я не знав, що ми можемо зробити $ouput = $array1 + $array2. Тепер я дізнався щось нове! Дякую!
Студент наук

1

Це працює:

$a = array(1 => 1, 2 => 2, 3 => 3);
$b = array(4 => 4, 5 => 5, 6 => 6);
$c = $a + $b;
print_r($c);

1

Увага! $ array1 + $ array2 перезаписує ключі, тому моє рішення (для багатовимірних масивів) полягає у використанні array_unique ()

array_unique(array_merge($a, $b), SORT_REGULAR);

Примітка:

5.2.10+ Змінено значення за замовчуванням дляsort_flags назад на SORT_STRING.

5.2.9 За замовчуванням SORT_REGULAR.

5.2.8 - За замовчуванням SORT_STRING

Це чудово працює . Сподіваюся, це допомагає так само.


1
array_merge()не зберігає ключі. Створений цим масив індексується 0.
HPierce

@HPierce, добре, у випадку багатовимірного додавання масиву деяка інформація буде втрачена при використанні +. Погляньте на: PHPFiddle , $ b [0] буде загублено ...
Норман Еденс

1

Новим способом зробити це за допомогою php7.4 є оператор Spread [...]

$parts = ['apple', 'pear'];
$fruits = ['banana', 'orange', ...$parts, 'watermelon'];
var_dump($fruits);

Оператор розвороту повинен мати кращу продуктивність, ніж array_merge

Суттєвою перевагою оператора Spread є те, що він підтримує будь-які об'єкти, що проходять, тоді як функція array_merge підтримує лише масиви.


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.