PHP array объединить ассоциативные массивы

Я пытаюсь добавить элемент в начало ассоциативного массива. Я решил, что лучший способ сделать это-использовать array_merge, но у меня есть некоторые странные последствия. Я получаю идентификатор и имя продуктов из базы данных mysql, и он возвращается как ассоциативный массив, например (не фактические данные возвращаются, но примеры данных для этого вопроса, который представляет, как выглядят данные приблизительно):

$products = array (1 => 'Product 1', 42 => 'Product 42', 100 => 'Product 100');

это отправляется помощнику html для создания раскрывающийся список, который связывает ключ со значением, а значение элемента массива устанавливается как текст в раскрывающемся элементе управления select. Мне нужно, чтобы первый элемент был чем-то вроде "Пожалуйста, выберите" с ключом 0, поэтому я сделал это:

$products = array_merge(array(0 => "Select a product" ), $products);

результирующий массив выглядит так:

            array(
                      0 => 'Select a product', 
                      1 => 'Product 1', 
                      2 => 'Product 42', 
                      3 => 'Product 100' 
                  );

когда я действительно хотел не потерять ключи ассоциативного массива. Мне сказали, что вы можете правильно использовать array_merge с ассоциативными массивами так, как я пытался, однако я верю, потому что мои ключи ints что он не рассматривает массив как истинный ассоциативный массив и сжимает их, как показано выше.

возникает вопрос: почему функция array_merge меняет ключи элементов? могу ли я удержать его от этого? Или есть другой способ выполнить то, что я пытаюсь сделать, добавить новый элемент в начале массива?

7 ответов


С docs:

Если вы хотите добавить элементы массива из второго массива в первом массиве, а не перезаписывая элементы из первого массива, а не повторной индексации, используйте + массив оператор Union

ключи из первого аргумента массива сохраняются при использовании + оператор объединения, поэтому изменение порядка ваших аргументов и использование оператора объединения должны делать то, что вам нужно:

$products = $products + array(0 => "Select a product");

просто для удовольствия

$newArray = array_combine(array_merge(array_keys($array1),
                                      array_keys($array2)
                                     ),
                          array_merge(array_values($array1),
                                      array_values($array2)
                                     )
                         );

array_merge будет пересчитывать числовые индексы. Потому что ваш ассоциативный массив iuses числовые индексы они будут перенумерованы. Вы либо вставляете нечисловой charadter перед индексами, как:

$products = array ('_1' => 'Product 1', '_42' => 'Product 42', '_100' => 'Product 100');

или вы можете создать результирующий массив вручную:

$newproducts = array (0 => "Select a product");
foreach ($products as $key => $value)
    $newproducts[$key] = $value;

можно использовать оператор массив: +

$products = array(0 => "Select a product" ) + $products;

он будет делать Союз и работает только тогда, когда ключи не пересекаются.


с docs:

значения во входном массиве с цифровыми ключами будут перенумерованы с помощью инкрементных ключей начиная с нуля в массиве результатов.


вы можете попробовать что-то вроде

$products[0]='Select a Product'
ksort($products);

Это должно поставить 0 в начале массива, но он также будет сортировать другие продукты в числовом порядке, который вы, возможно, не захотите.


вы хотите посмотреть на функцию array_replace.

в этом примере они функционируют одинаково:

$products1 = array (1 => 'Product 1', 42 => 'Product 42', 100 => 'Product 100');
$products2 = array (0 => 'Select a product');

$result1 = array_replace($products1, $products2);
$result2 = $products1 + $products2;

Result for both result1 and result2: Keys are preserved:
array(4) {
  [1] => string(9) "Product 1"
  [42] => string(10) "Product 42"
  [100] => string(11) "Product 100"
  [0] => string(16) "Select a product"
}

однако они отличаются если один и тот же ключ присутствует в обоих массивах: оператор + не перезаписывает значение, array_replace делает.