展开“点符号"嵌套数组中的子数组键 [英] Expand "dot notation" keys in a nested array to child arrays

查看:137
本文介绍了展开“点符号"嵌套数组中的子数组键的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I start with a nested array of some arbitrary depth. Within that array, some keys are a series of tokens separated by dots. For example "billingAddress.street" or "foo.bar.baz". I would like to expand those keyed elements to arrays, so the result is a nested array with all those keys expanded.

例如:

[
    'billingAddress.street' => 'My Street',
    'foo.bar.baz' => 'biz',
]

应扩展为:

[
    'billingAddress' => [
        'street' => 'My Street',
    ],
    'foo' => [
        'bar' => [
            'baz' => 'biz',
        ]
    ]
]

原始的"billingAddress.street"可以与新的"billingAddress"数组并排放置,但是不必保留(因此解决方案可以在原始数组上运行或创建新的数组).诸如"billingAddress.city"之类的其他元素可能需要添加到数组的同一扩展部分.

The original "billingAddress.street" can be left alongside the new "billingAddress" array, but it does not need to be (so the solution may operate on the original array or create a new array). Other elements such as "billingAddress.city" may need to be added to the same expanded portion of the array.

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

Some keys may have more than two tokens separated by dots, so will need to be expanded deeper.

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

I've looked at array_walk_recursive() but that only operates on elements. For each matching element key, I actually want to modify the parent array those elements are in.

我看过array_map,但是它不提供对键的访问,而且据我所知,它不是递归的.

I've looked at array_map, but that does not provide access to the keys, and as far as I know is not recursive.

要扩展的示例数组:

[
    'name' => 'Name',
    'address.city' => 'City',
    'address.street' => 'Street',
    'card' => [
        'type' => 'visa',
        'details.last4' => '1234',
    ],
]

这将被扩展为:

[
    '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',
        ],
    ],
]

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

What I think I need, is something that walks to each array in the nested array and can apply a user function to it. But I do suspect I'm missing something obvious. The payment gateway I am working with sends me this mix of arrays and "pretend arrays" using the dot-notation, and my objective is to normalize it into an array for extracting portions.

我相信这个问题与SO上的类似问题有所不同,这是因为阵列和非阵列的混合使用以进行扩展.从概念上讲,它是一个嵌套数组,其中需要用新数组替换 any 级别的元素的 groups 元素,因此这里发生了两个递归级别:树行走,然后展开,然后沿着展开的树木走动,以查看是否需要更多的展开.

I believe the problem differs from similar questions on SO due to this mix of arrays and non-arrays for expanding. Conceptually it is a nested array where sound groups of elements at any level need to be replaced with new arrays, so there are two levels of recursion happening here: the tree walking, and the expansion, and then the walking of the expanded trees to see if there is more expansion needed.

推荐答案

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

You could find it useful to reverse the order of the keys you get from exploding the combined (dotted) key. In that reversed order it is easier to progressively wrap a previous result into a new array, thereby creating the nested result for one dotted key/value pair.

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

Finally, that partial result can be merged into the accumulated "grand" result with the built-in array_merge_recursive function:

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

看到它在 repl.it

这篇关于展开“点符号"嵌套数组中的子数组键的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆