PHP 中 2 个数组的多个值到一个键
Multiple values to one key from 2 arrays in PHP
我想将 2 个数组与 array_combine 结合起来。我希望 Array1 的值是我的键,Array2 的值是我的值。
这些值来自一个 .yml 文件,其中 componentgroup 作为 Key,componentname 作为 Value
$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" 有更多的值(可能是一个值数组)。
有什么想法吗?谢谢。
$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;
}
您的代码不起作用的原因是 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"
}
由于 "problem" 是 FOO 键,我将解释代码对该键的作用。
代码使用 array_intersect 找到 "FOO" 键和 return:
array(2) {
[0]=>
string(3) "FOO"
[3]=>
string(3) "FOO"
}
请注意键与您的原始数组匹配。
这在 array_intersect_key 中使用,它使用键编号并使用匹配的键从值数组中获取值。
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"
}
由于计数大于 1,因此 if()
将为真并且 $temp-array 被添加到 $yamlMap 的键 "FOO"。
如果它只是数组中的一项,则只会添加单个字符串,因此不会添加多维
这是一种更直接的方法:
代码:(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',
)
初步解决方案:
遍历您的数据一次,将其归结为二维数组,然后使用 array_merge_recursive()
的魔法将其转换为您想要的输出。 ...
是 splat 运算符,它告诉 array_merge_recursive()
将 $result
视为一系列 1-dim 数组而不是 2-dim 数组。
代码:(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 个数组与 array_combine 结合起来。我希望 Array1 的值是我的键,Array2 的值是我的值。 这些值来自一个 .yml 文件,其中 componentgroup 作为 Key,componentname 作为 Value
$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" 有更多的值(可能是一个值数组)。
有什么想法吗?谢谢。
$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;
}
您的代码不起作用的原因是 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"
}
由于 "problem" 是 FOO 键,我将解释代码对该键的作用。
代码使用 array_intersect 找到 "FOO" 键和 return:
array(2) {
[0]=>
string(3) "FOO"
[3]=>
string(3) "FOO"
}
请注意键与您的原始数组匹配。
这在 array_intersect_key 中使用,它使用键编号并使用匹配的键从值数组中获取值。
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"
}
由于计数大于 1,因此 if()
将为真并且 $temp-array 被添加到 $yamlMap 的键 "FOO"。
如果它只是数组中的一项,则只会添加单个字符串,因此不会添加多维
这是一种更直接的方法:
代码:(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',
)
初步解决方案:
遍历您的数据一次,将其归结为二维数组,然后使用 array_merge_recursive()
的魔法将其转换为您想要的输出。 ...
是 splat 运算符,它告诉 array_merge_recursive()
将 $result
视为一系列 1-dim 数组而不是 2-dim 数组。
代码:(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',
)