将嵌套数组中的“点表示法”键扩展为子数组

Jas*_*son 3 php arrays recursion adyen

我从一些任意深度的嵌套数组开始。在该数组中,某些键是一系列用点分隔的令牌。例如“ billingAddress.street”或“ foo.bar.baz”。我想将这些键元素扩展为数组,因此结果是所有这些键都扩展了的嵌套数组。

例如:

[
    'billingAddress.street' => 'My Street',
    'foo.bar.baz' => 'biz',
]
Run Code Online (Sandbox Code Playgroud)

应该扩展为:

[
    'billingAddress' => [
        'street' => 'My Street',
    ],
    'foo' => [
        'bar' => [
            'baz' => 'biz',
        ]
    ]
]
Run Code Online (Sandbox Code Playgroud)

可以在新的“ billingAddress”数组旁边保留原始的“ billingAddress.street”,但这不是必须的(因此解决方案可以在原始数组上运行或创建新的数组)。可能需要将其他元素(例如“ billingAddress.city”)添加到数组的同一扩展部分。

某些键可能有两个以上的令牌,这些令牌由点分隔,因此需要更深地扩展。

我已经看过了,array_walk_recursive()但这仅适用于元素。对于每个匹配的元素键,我实际上想修改这些元素所在的父数组。

我已经看过array_map,但是它不提供对键的访问,并且据我所知不是递归的。

扩展示例数组:

[
    'name' => 'Name',
    'address.city' => 'City',
    'address.street' => 'Street',
    'card' => [
        'type' => 'visa',
        'details.last4' => '1234',
    ],
]
Run Code Online (Sandbox Code Playgroud)

这将扩展为:

[
    'name' => 'Name',
    'address.city' => 'City', // Optional
    'address' => [
        'city' => 'City',
        'street' => 'Street',
    ],
    'address.street' => 'Street', // Optional
    'card' => [
        'type' => 'visa',
        'details.last4' => '1234', // Optional
        'details' => [
            'last4' => '1234',
        ],
    ],
]
Run Code Online (Sandbox Code Playgroud)

我认为我需要的是可以遍历array嵌套数组中的每个数组并可以对其应用用户功能的东西。但是我确实怀疑我缺少明显的东西。我正在使用的支付网关使用点符号将此数组和“假装数组”的混合发送给我,我的目标是将其规范化为数组以提取部分。

我相信这个问题与SO上的类似问题有所不同,这是由于阵列和非阵列的这种混合扩展。从概念上讲,它是一个嵌套数组,其中任何级别的声音元素都需要用新数组替换,因此这里发生了两个递归级别:树遍历和展开,然后遍历展开的树以查看如果需要更多扩展。

tri*_*cot 5

您可能会发现颠倒组合键(虚线)后得到的键顺序很有用。按照这种相反的顺序,将以前的结果逐步包装到新数组中会更容易,从而为一个点分键/值对创建嵌套结果。

最后,可以使用内置array_merge_recursive函数将该部分结果合并为累积的“大”结果:

function expandKeys($arr) {
    $result = [];
    foreach($arr as $key => $value) {
        if (is_array($value)) $value = expandKeys($value);
        foreach(array_reverse(explode(".", $key)) as $key) $value = [$key => $value];
        $result = array_merge_recursive($result, $value);
    }
    return $result;
}
Run Code Online (Sandbox Code Playgroud)

看到它在repl.it上运行