根据键的值合并数组
Merging arrays based on a value of the key
我有两个具有 id
键的数组数组,我想根据该数组的键和键值将数据合并在一起。数据看起来像:
$color = [
['id' => 1, 'color' => 'red'],
['id' => 2, 'color' => 'green'],
['id' => 3, 'color' => 'blue'],
];
$size = [
['id' => 1, 'size' => 'SM'],
['id' => 2, 'size' => 'XL'],
['id' => 3, 'size' => 'MD'],
['id' => 4, 'size' => 'LG'],
];
$combined = [
['id' => 1, 'color' => 'red', 'size' => 'SM'],
['id' => 2, 'color' => 'green', 'size' => 'XL'],
['id' => 3, 'color' => 'blue', 'size' => 'MD'],
['id' => 4, 'size' => 'LG'],
];
有没有特别有效的函数或技巧来处理这样的事情?或者我应该循环遍历一个数组的元素并将内容推送到另一个?
我也在使用 Laravel,数据是 eloquent 查询的结果,所以我也可以使用这些集合,如果它可以使代码更清晰的话。
尝试:
$out = array();
foreach ($size as $key => $value){
if(!isset($color[$key])) { $color[$key] = array(); }
$out[] = array_merge((array)$value,(array)$color[$key]);
}
输出:
Array
(
[0] => Array
(
[id] => 1
[size] => SM
[color] => red
)
[1] => Array
(
[id] => 2
[size] => XL
[color] => green
)
[2] => Array
(
[id] => 3
[size] => MD
[color] => blue
)
[3] => Array
(
[id] => 4
[size] => LG
)
)
使用array_replace_recursive函数,方便快捷
array_replace_recursive($color, $size)
使用循环的更好方法。首先通过count这个数运行一个循环来计算max数组。它会起作用。
简单的嵌套循环就可以解决这个问题。
foreach($size as $key => $value1) {
foreach($color as $value2) {
if($value1['id'] === $value2['id']){
$size[$key]['color'] = $value2['color'];
}
}
}
echo '<pre>';
print_r($size);
输出:
Array
(
[0] => Array
(
[id] => 1
[size] => SM
[title] => red
)
[1] => Array
(
[id] => 2
[size] => XL
[title] => green
)
[2] => Array
(
[id] => 3
[size] => MD
[title] => blue
)
[3] => Array
(
[id] => 4
[size] => LG
)
)
您可以使用 array_replace_recursive
在您的特定情况下合并数组。
$color = array(
array('id' => 1, 'color' => 'red'),
array('id' => 2, 'color' => 'green'),
array('id' => 3, 'color' => 'blue'),
);
$size = array(
array('id' => 1, 'size' => 'SM'),
array('id' => 2, 'size' => 'XL'),
array('id' => 3, 'size' => 'MD'),
array('id' => 4, 'size' => 'LG'),
);
$merged = array_replace_recursive($color, $size);
输出:
array(4) {
[0]=>
array(3) {
["id"]=>
int(1)
["color"]=>
string(3) "red"
["size"]=>
string(2) "SM"
}
[1]=>
array(3) {
["id"]=>
int(2)
["color"]=>
string(5) "green"
["size"]=>
string(2) "XL"
}
[2]=>
array(3) {
["id"]=>
int(3)
["color"]=>
string(4) "blue"
["size"]=>
string(2) "MD"
}
[3]=>
array(2) {
["id"]=>
int(4)
["size"]=>
string(2) "LG"
}
}
注意:我使用了传统的数组布局,因为我的PHP版本还不支持新的:)
第二个选项
您也可以使用array_map
。这将允许您通过一些微调添加任意数量的数组。
$merged = array_map(function ($c, $s) {
return array_merge($c, $s);
}, $color, $size);
var_dump($merged); // See output above
我建议使用 laravel 的集合,因为这个问题有 laravel 标签。
$color = collect(
['id' => 1, 'color' => 'red'],
['id' => 2, 'color' => 'green'],
['id' => 3, 'color' => 'blue']
);
$size = collect(
['id' => 1, 'size' => 'SM'],
['id' => 2, 'size' => 'XL'],
['id' => 3, 'size' => 'MD'],
['id' => 4, 'size' => 'LG']
);
$combined = $color->merge($size);
纯 php 解决方案是这样使用 array_replace_recursive:
array_replace_recursive(
array_combine(array_column($color, "id"), $color),
array_combine(array_column($size, "id"), $size)
);
您应该注意到 array_replace_recursive
通过键合并数组。
因此,如果您从数据库中获取此类数据:
$color = [
['id' => 1, 'color' => 'red'],
['id' => 2, 'color' => 'red']
];
$size = [
['id' => 2, 'size' => 'SM']
];
array_replace_recursive
将 return 损坏 合并:
$combined = [
['id' => 2, 'color' => 'red', 'size' => 'SM'],
['id' => 2, 'color' => 'red']
];
解决方案是将 array_replace_recursive
与 array_column
和 array_combine
结合起来,通过它们的 id
字段合并数组:
array_replace_recursive(
array_combine(array_column($color, "id"), $color),
array_combine(array_column($size, "id"), $size)
);
array_combine(array_column($color, "id"), $color)
创建以 id
作为键的关联数组。
因此,在您的情况下它将 return:
$combined = [
1 => ['id' => 1, 'color' => 'red', 'size' => 'SM'],
2 => ['id' => 2, 'color' => 'green', 'size' => 'XL'],
3 => ['id' => 3, 'color' => 'blue', 'size' => 'MD'],
4 => ['id' => 4, 'size' => 'LG'],
];
关注这个:
array_replace_recursive() 是递归的:它将递归到数组并对内部值应用相同的过程。
$combined = array_replace_recursive($color, $size);
然后您可以打印以查看如下结果:
print_r($combined);
您需要一个一个地遍历两个数组中的所有元素,并合并任何重复的元素。为此,您需要执行以下步骤。
将两个数组粘合在一起。
$arr = [
['id' => 1, 'color' => 'red'],
['id' => 2, 'color' => 'green'],
['id' => 3, 'color' => 'blue'],
['id' => 1, 'size' => 'SM'],
['id' => 2, 'size' => 'XL'],
['id' => 4, 'size' => 'LG'],
['id' => 3, 'size' => 'MD'],
];
循环组合数组,将项目复制到新数组中。
如果 ID 以前见过,则不要追加该行,而是将其与现有行合并。
您可以通过一个 foreach
循环和 array_merge
实现所有这些。不需要递归函数或嵌套循环。
// Loops on merged arrays and copied elements into a new array
foreach(array_merge($color, $size) as $el){
// If the element with this id is already in new array then add the elements together
$merged[$el['id']] = ($merged[$el['id']] ?? []) + $el;
}
唯一的缺点是你丢失了原始索引,但从你的问题来看这对你来说并不重要。如果需要,可以使用
重新索引数组
$merged = array_values($merged);
我有两个具有 id
键的数组数组,我想根据该数组的键和键值将数据合并在一起。数据看起来像:
$color = [
['id' => 1, 'color' => 'red'],
['id' => 2, 'color' => 'green'],
['id' => 3, 'color' => 'blue'],
];
$size = [
['id' => 1, 'size' => 'SM'],
['id' => 2, 'size' => 'XL'],
['id' => 3, 'size' => 'MD'],
['id' => 4, 'size' => 'LG'],
];
$combined = [
['id' => 1, 'color' => 'red', 'size' => 'SM'],
['id' => 2, 'color' => 'green', 'size' => 'XL'],
['id' => 3, 'color' => 'blue', 'size' => 'MD'],
['id' => 4, 'size' => 'LG'],
];
有没有特别有效的函数或技巧来处理这样的事情?或者我应该循环遍历一个数组的元素并将内容推送到另一个?
我也在使用 Laravel,数据是 eloquent 查询的结果,所以我也可以使用这些集合,如果它可以使代码更清晰的话。
尝试:
$out = array();
foreach ($size as $key => $value){
if(!isset($color[$key])) { $color[$key] = array(); }
$out[] = array_merge((array)$value,(array)$color[$key]);
}
输出:
Array
(
[0] => Array
(
[id] => 1
[size] => SM
[color] => red
)
[1] => Array
(
[id] => 2
[size] => XL
[color] => green
)
[2] => Array
(
[id] => 3
[size] => MD
[color] => blue
)
[3] => Array
(
[id] => 4
[size] => LG
)
)
使用array_replace_recursive函数,方便快捷
array_replace_recursive($color, $size)
使用循环的更好方法。首先通过count这个数运行一个循环来计算max数组。它会起作用。
简单的嵌套循环就可以解决这个问题。
foreach($size as $key => $value1) {
foreach($color as $value2) {
if($value1['id'] === $value2['id']){
$size[$key]['color'] = $value2['color'];
}
}
}
echo '<pre>';
print_r($size);
输出:
Array
(
[0] => Array
(
[id] => 1
[size] => SM
[title] => red
)
[1] => Array
(
[id] => 2
[size] => XL
[title] => green
)
[2] => Array
(
[id] => 3
[size] => MD
[title] => blue
)
[3] => Array
(
[id] => 4
[size] => LG
)
)
您可以使用 array_replace_recursive
在您的特定情况下合并数组。
$color = array(
array('id' => 1, 'color' => 'red'),
array('id' => 2, 'color' => 'green'),
array('id' => 3, 'color' => 'blue'),
);
$size = array(
array('id' => 1, 'size' => 'SM'),
array('id' => 2, 'size' => 'XL'),
array('id' => 3, 'size' => 'MD'),
array('id' => 4, 'size' => 'LG'),
);
$merged = array_replace_recursive($color, $size);
输出:
array(4) {
[0]=>
array(3) {
["id"]=>
int(1)
["color"]=>
string(3) "red"
["size"]=>
string(2) "SM"
}
[1]=>
array(3) {
["id"]=>
int(2)
["color"]=>
string(5) "green"
["size"]=>
string(2) "XL"
}
[2]=>
array(3) {
["id"]=>
int(3)
["color"]=>
string(4) "blue"
["size"]=>
string(2) "MD"
}
[3]=>
array(2) {
["id"]=>
int(4)
["size"]=>
string(2) "LG"
}
}
注意:我使用了传统的数组布局,因为我的PHP版本还不支持新的:)
第二个选项
您也可以使用array_map
。这将允许您通过一些微调添加任意数量的数组。
$merged = array_map(function ($c, $s) {
return array_merge($c, $s);
}, $color, $size);
var_dump($merged); // See output above
我建议使用 laravel 的集合,因为这个问题有 laravel 标签。
$color = collect(
['id' => 1, 'color' => 'red'],
['id' => 2, 'color' => 'green'],
['id' => 3, 'color' => 'blue']
);
$size = collect(
['id' => 1, 'size' => 'SM'],
['id' => 2, 'size' => 'XL'],
['id' => 3, 'size' => 'MD'],
['id' => 4, 'size' => 'LG']
);
$combined = $color->merge($size);
纯 php 解决方案是这样使用 array_replace_recursive:
array_replace_recursive(
array_combine(array_column($color, "id"), $color),
array_combine(array_column($size, "id"), $size)
);
您应该注意到 array_replace_recursive
通过键合并数组。
因此,如果您从数据库中获取此类数据:
$color = [
['id' => 1, 'color' => 'red'],
['id' => 2, 'color' => 'red']
];
$size = [
['id' => 2, 'size' => 'SM']
];
array_replace_recursive
将 return 损坏 合并:
$combined = [
['id' => 2, 'color' => 'red', 'size' => 'SM'],
['id' => 2, 'color' => 'red']
];
解决方案是将 array_replace_recursive
与 array_column
和 array_combine
结合起来,通过它们的 id
字段合并数组:
array_replace_recursive(
array_combine(array_column($color, "id"), $color),
array_combine(array_column($size, "id"), $size)
);
array_combine(array_column($color, "id"), $color)
创建以 id
作为键的关联数组。
因此,在您的情况下它将 return:
$combined = [
1 => ['id' => 1, 'color' => 'red', 'size' => 'SM'],
2 => ['id' => 2, 'color' => 'green', 'size' => 'XL'],
3 => ['id' => 3, 'color' => 'blue', 'size' => 'MD'],
4 => ['id' => 4, 'size' => 'LG'],
];
关注这个: array_replace_recursive() 是递归的:它将递归到数组并对内部值应用相同的过程。
$combined = array_replace_recursive($color, $size);
然后您可以打印以查看如下结果:
print_r($combined);
您需要一个一个地遍历两个数组中的所有元素,并合并任何重复的元素。为此,您需要执行以下步骤。
将两个数组粘合在一起。
$arr = [ ['id' => 1, 'color' => 'red'], ['id' => 2, 'color' => 'green'], ['id' => 3, 'color' => 'blue'], ['id' => 1, 'size' => 'SM'], ['id' => 2, 'size' => 'XL'], ['id' => 4, 'size' => 'LG'], ['id' => 3, 'size' => 'MD'], ];
循环组合数组,将项目复制到新数组中。
如果 ID 以前见过,则不要追加该行,而是将其与现有行合并。
您可以通过一个 foreach
循环和 array_merge
实现所有这些。不需要递归函数或嵌套循环。
// Loops on merged arrays and copied elements into a new array
foreach(array_merge($color, $size) as $el){
// If the element with this id is already in new array then add the elements together
$merged[$el['id']] = ($merged[$el['id']] ?? []) + $el;
}
唯一的缺点是你丢失了原始索引,但从你的问题来看这对你来说并不重要。如果需要,可以使用
重新索引数组$merged = array_values($merged);