PHP array_merge关联数组

27

我尝试将一个元素添加到关联数组的开头。我认为最好的方法是使用array_merge,但是我遇到了一些奇怪的后果。我从mysql数据库中获取产品的id和Name,并将其作为关联数组返回,就像这样(不是实际返回的数据,而是针对此问题表示数据外观的示例数据):

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

这将被发送到一个HTML助手来创建一个下拉列表,将键与值相关联,数组项的值设置为下拉选择控件中的文本。 我需要第一项类似于“请选择”,其键为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与关联数组,但是我认为由于我的键是整数,它没有将数组视为真正的关联数组,并像上面所示一样压缩它们。

问题是:为什么array_merge函数会更改项的键?我可以防止它这样做吗?还是有其他方法可以实现我想要做的事情,将新项目添加到数组的开头?


我曾经遇到过使用array_merge()时出现的完全相同的问题。我不确定这是否是一个错误,或者我们正在尝试以一种意外的方式使用它。解决方案是通过快速foreach循环来重建您的数组。从$myarray = array(0 => '选择产品')开始。 - jjwdesign
7个回答

57
docs中:

如果你想要将第二个数组的元素追加到第一个数组中,而不覆盖第一个数组的元素并且不重新索引,可以使用+数组合并运算符

使用+合并运算符时,第一个数组参数的键会被保留,所以反转参数的顺序并使用合并运算符应该可以满足你的需求:

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

1
但是这样不会将“选择一个产品”附加到数组的末尾吗? - Bob Fanger
@Bob:这是一次合并,而不是追加;无论哪种方式,联合运算符都会保留键,因此只要 $products 中没有已存在的键“0”,那么合并后就会有。 - Mark Elliot
1
我正在尝试 $products = array(0 => "选择一个产品") + $products; 测试... 它起作用了,谢谢。有很多不同的方法和方式来操作数组,这让人感到困惑。 - stephenbayer

6

只是为了好玩

,与IT技术无关。
$newArray = array_combine(array_merge(array_keys($array1),
                                      array_keys($array2)
                                     ),
                          array_merge(array_values($array1),
                                      array_values($array2)
                                     )
                         );

4

array_merge函数会重新计算数组的数字索引。因为你的关联数组使用了数字索引,所以他们将被重新编号。你可以在索引前面插入一个非数字字符来避免这个问题,例如:

$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;

我已经弄清楚了,我尝试过的一件事情是将键转换为字符串,所以我使用的是'1'而不是1,但它仍然像数值int一样处理它,php类型的弱点是我需要习惯的,因为我来自C背景,有更强的类型。 - stephenbayer

2
您可以使用数组运算符+
$products = array(0 => "Select a product" ) + $products;

它将执行一个联合操作,仅在键不重叠时有效。

是的,那就是解决方案,但有人先发布了。但我仍然点赞了,我不知道+运算符可以这样使用,无论如何感谢你的答案。 - stephenbayer

1

来自文档

输入数组中具有数字键的值将使用从零开始的递增键在结果数组中重新编号。


1
你可能想要查看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 则会。

完美。这应该是被接受的答案,因为被接受的答案无法解决重复键问题。 - Jiro Matchonson

0
你可以尝试类似这样的东西。
$products[0]='Select a Product'
ksort($products);

这将把0放在数组的开头,但它也会按数字顺序排序其他产品,这可能不是您想要的。


是的,客户希望以某种混乱的任意顺序显示,<select>选项在原始应用程序中是硬编码的,因此当他们添加新产品时,之前的开发人员必须将它们添加到<options>中,而我绝对拒绝这样做,因为这是一种可怕的反模式,所以我只是在产品编辑屏幕上添加了一个排序选项。 - stephenbayer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接