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

https://3v4l.org/FtjQC

您的代码不起作用的原因是 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"
}

https://3v4l.org/hu2re

由于 "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',
)