我想结合使用array_combine的2个数组。我希望Array1的值是我的键,而Array2的值是我的值。 这些值来自一个.yml文件,该文件的组件组为键,组件名称为值
$yamlKeys = array();
foreach ($yaml['components'] as $yamlComponent) {
array_push($yamlKeys, $yamlComponent['cachet']['componentgroup']);
}
$yamlValues = array();
foreach ($yaml['components'] as $yamlComponent) {
array_push($yamlValues, $yamlComponent['cachet']['componentname']);
}
$yamlMap = array();
$yamlMap = array_combine($yamlKeys, $yamlValues);
echo("===== YAML MAP STARTS =====");
var_dump($yamlMap);
echo("===== YAML MAP ENDS =====");
我的问题: 可以有同名的钥匙。 在$ yamlMap中,只会分配一个值(最后一个)。例如:
Yaml文件看起来像这样:
FOO => BAR
Key1 => Value1
Key2 => Value2
FOO => BAZ
Key3 => Value3
我的代码可以:
FOO => BAZ
Key1 => Value1
Key2 => Value2
Key3 => Value3
但是我想要这样:
FOO => BAR, BAZ
Key1 => Value1
Key2 => Value2
Key3 => Value3
更准确地说:如果有更多的“ FOO”键,我希望“ FOO”具有更多的值(也许是值的数组)。
有什么主意吗?谢谢。
答案 0 :(得分:0)
您的代码不起作用的原因是因为array_combine需要唯一键。因此,循环是获取期望值的唯一方法。
这是我循环唯一键并使用array_intersect(_key)获取匹配值的一种方法。
如果计数不止一个,我知道输出子数组应该是数组。
否则,它是[0]项目中的单个值(由于array_values),我只添加了它。
$yamlKeys = ["FOO","Key1","Key2","FOO","Key3"];
$yamlValues = ["BAR","Value1","Value2","BAZ","Value3"];
$yamlMap = [];
foreach(array_unique($yamlKeys) as $key => $ykey){
$temp = array_values(array_intersect_key($yamlValues,array_intersect($yamlKeys, [$ykey])));
if(count($temp)>1){
$yamlMap[$ykey] = $temp;
}else{
$yamlMap[$ykey] = $temp[0];
}
}
var_dump($yamlMap);
输出:
array(4) {
["FOO"]=>
array(2) {
[0]=>
string(3) "BAR"
[1]=>
string(3) "BAZ"
}
["Key1"]=>
string(6) "Value1"
["Key2"]=>
string(6) "Value2"
["Key3"]=>
string(6) "Value3"
}
由于“问题”是FOO键,因此我将解释代码对该键的作用。
代码使用array_intersect查找“ FOO”键并返回:
array(2) {
[0]=>
string(3) "FOO"
[3]=>
string(3) "FOO"
}
请注意,键与原始数组匹配。
在array_intersect_key中使用它,它使用键编号并使用匹配的键从values数组中获取值。
array(2) {
[0]=>
string(3) "BAR"
[3]=>
string(3) "BAZ"
}
然后我使用array_values来设置键0、1。
$ temp现在看起来像
array(2) {
[0]=>
string(3) "BAR"
[1]=>
string(3) "BAZ"
}
由于计数多于一个,if()
将为true,并将$ temp-array添加到$ yamlMap的键“ FOO”中。
如果它只是数组中的一项,则只会添加单个字符串,因此不会是多维的
答案 1 :(得分:0)
这是一种更直接的方法:
代码:(Demo)(or this alternative/condensed version)
$yamlMap = [];
foreach ($yaml['components'] as $yamlComponent) {
$key = $yamlComponent['cachet']['componentgroup'];
$value = $yamlComponent['cachet']['componentname'];
if (isset($yamlMap[$key])) {
if (is_array($yamlMap[$key])) {
$yamlMap[$key][] = $value; // push to existing array
} else {
$yamlMap[$key] = [$yamlMap[$key], $value]; // convert string to array containing old string and new string
}
} else {
$yamlMap[$key] = $value; // save first occurrence as a string
}
}
var_export($yamlMap);
输出:
array (
'FOO' =>
array (
0 => 'BAR',
1 => 'BAZ',
),
'Key1' => 'Value1',
'Key2' => 'Value2',
'Key3' => 'Value3',
)
初始解决方案:
迭代一次数据,将其精简为2维数组,然后使用array_merge_recursive()
的魔力将其转换为所需的输出。 ...
是splat运算符,它告诉array_merge_recursive()
将$result
视为一系列1维数组而不是2维数组。
代码:(Demo)
foreach ($yaml as $components) {
foreach ($components as $sets) {
foreach ($sets as $cachet) {
$result[] = [$cachet['componentgroup'] => $cachet['componentname']];
}
}
}
var_export(array_merge_recursive(...$result));
我的解决方案从您未曾动过的$yaml
变量开始。
$yaml = [
'components' => [
[
'cachet' => [
'componentgroup' => 'FOO',
'componentname' => 'BAR'
]
],
[
'cachet' => [
'componentgroup' => 'Key1',
'componentname' => 'Value1'
]
],
[
'cachet' => [
'componentgroup' => 'Key2',
'componentname' => 'Value2'
]
],
[
'cachet' => [
'componentgroup' => 'FOO',
'componentname' => 'BAZ'
]
],
[
'cachet' => [
'componentgroup' => 'Key3',
'componentname' => 'Value3'
]
]
]
];
输出:
array (
'FOO' =>
array (
0 => 'BAR',
1 => 'BAZ',
),
'Key1' => 'Value1',
'Key2' => 'Value2',
'Key3' => 'Value3',
)
答案 2 :(得分:-3)
$yamlMap = [];
foreach ($yaml['components'] as $yamlComponent) {
$key = $yamlComponent['cachet']['componentgroup'];
$value = $yamlComponent['cachet']['componentname'];
// Lets initialize the key to be an array so that we may collect multiple values
if(!array_key_exists($key, $yamlMap)) {
$yamlMap[$key] = [];
}
// lets add the value to the map under the key
$yamlMap[$key][] = $value;
}