我有一个关联数组:
$input = [
['key'=>'x', 'value'=>'a'],
['key'=>'x', 'value'=>'b'],
['key'=>'x', 'value'=>'c'],
['key'=>'y', 'value'=>'d'],
['key'=>'y', 'value'=>'e'],
['key'=>'z', 'value'=>'f'],
['key'=>'m', 'value'=>'n'],
];
我想简单地改革它:
$output = [
'x'=>['a','b','c'],
'y'=>['d','e'],
'z'=>'f',
'm'=>'n'
]
基本上,条件是:
1. If same key found then put values in an array.
2. If no same key found then value remains string.
如果您对对象更熟悉,可以用对象替换关联数组。
以下是我解决此问题的方法:
foreach($input as $in){
if(!empty($output[$in['key']])){
if(is_array($output[$in['key']])){
$output[$in['key']][] = $in['value'];
continue;
}
$output[$in['key']] = [$output[$in['key']],$in['value']];
continue;
}
$output[$in['key']] = $in['value'];
}
print_r($output);
但我相信它可以以紧凑而有效的方式完成。 如果有人有更好的解决方案,请评论您的答案 非常感谢您的帮助!
答案 0 :(得分:7)
将数组重新格式化为[[x => a],[x => b],..]并合并所有子数组
$input = array_map(function($x) { return [$x['key'] => $x['value']]; }, $input);
$input = array_merge_recursive(...$input);
print_r($input);
答案 1 :(得分:2)
我建议
<?php
$input = [
['key'=>'x', 'value'=>'a'],
['key'=>'x', 'value'=>'b'],
['key'=>'x', 'value'=>'c'],
['key'=>'y', 'value'=>'d'],
['key'=>'y', 'value'=>'e'],
['key'=>'z', 'value'=>'f'],
['key'=>'m', 'value'=>'n'],
];
$reducer = function($carry, $item) {
$carry[$item['key']][] = $item['value'];
return $carry;
};
$mapper = function ($item) {
if (count($item) === 1) {
return $item[0];
}
return $item;
};
$output = array_map($mapper, array_reduce($input, $reducer, []));
var_dump($output);
您可以在此处查看结果:https://3v4l.org/8JjjS
答案 2 :(得分:1)
您可以使用array_reduce
循环遍历现有阵列并构建一个新阵列:
$output = array_reduce($input, function ($carry, $i) {
$carry[$i['key']][] = $i['value'];
return $carry;
}, []);
$input
中的每个元素都会传递给匿名函数,以及随着我们一起构建的$carry
变量。在内部,我们只需将每个value
添加到由key
索引的子元素中。第三个参数[]
是将结果的初始值设置为空数组。
(我假设问题中的重复x
键是拼写错误,而第二个键应该是z
,因为它与您建议的输出匹配)
答案 3 :(得分:0)
对于原始代码,您可能会发现extract()
很有趣。我将continue
- s替换为else
- s,但这更像是一种品味:
foreach($input as $in){
extract($in);
if(!empty($output[$key])){
if(is_array($output[$key])){
$output[$key][] = $value;
} else {
$output[$key] = [$output[$key],$value];
}
} else {
$output[$key] = $value;
}
另一方面,我可能会使用两个更简单的循环,一个用于构建列表,另一个用于提取单个元素:
foreach($input as $in){
$output[$in['key']][] = $in['value'];
/* or: extract($in);
$output[$key][]=$value; */
}
foreach($output as $key => $value){
if(count($value)==1){
$output[$key]=$value[0];
}
}