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


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.