微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何将带有表示数字列表“1.1.1”的键的对象转换为多维数组

如何解决如何将带有表示数字列表“1.1.1”的键的对象转换为多维数组

假设我有以下 plain 对象:

var numberedList = {
    "1": "Text of 1","1.1": ["array of 1.1"],"1.2": {
        key: "object of 1.2"
    },"1.1.1": 999,"1.2.1": true,"1.2.2": function () {
        return "function of 1.2.2";
    },"1.3": null,"2": 2
}

我想完成如下多维数组:

简单解释一下:

[
    ["1",[
            [
                [
                    "1.1",[
                        "1.1.1"
                    ]
                ]
            ],[
                [
                    "1.2",[
                        "1.2.1","1.2.2"
                    ]
                ],],"1.3"
        ]
    ],"2"
]

最终数组:

[
    [
        "Text of 1",[
            [
                [
                    ["array of 1.1"],[
                        999
                    ]
                ]
            ],[
                [
                    {
                        key: "object of 1.2"
                    },[
                        true,function()
                        {
                            return "function of 1.2.2";
                        }
                    ]
                ],null
        ]
    ],2
]

请注意,最深的元素不会包装到数组中。

如何在纯 vanilla js 中执行通用递归函数来完成此操作?

主要目标是执行 console.group() 调用树,例如 console.groupEnd() 也将在每个树分支的末尾调用。如果顶部的对象执行这些控制台调用,那么帮助我完成这也是一个奖励。

解决方法

这是我的解决方案,

var numberedList = { "1": "Text of 1","1.1": ["array of 1.1"],"1.2": { key: "object of 1.2" },"1.1.1": 999,"1.2.1": true,"1.2.2": function () { return "function of 1.2.2"; },"1.3": null,"2": 2 }


function gen(numberedList) {
    let result = Object.keys(numberedList).reduce((res,key) => {
        let indexs = key.split(".");
        let lastindex = indexs.pop()
        indexs.reduce((res,i) => res[i],res)[lastindex] = [key]
        return res
    },[]);

    result.shift(); // Removing first item,Becouse index count from 0;
    return result
}

console.log(gen(numberedList))

您需要创建一个 trimer 函数来修剪此结果,以删除括号 ([])

,

首先,将来,请在问题中包含您尝试使用的代码或至少一个相关版本。参考 JSFiddle 或类似内容来获取额外的上下文不是问题,但如果没有它,问题应该足够完整。


这里我使用了一个通用的辅助函数 setPath,它接受​​一个路径,比如 ['foo','bar','baz'],一个新的结果,比如说,'new result',并创建一个嵌套对象/数组的更新副本将该路径上的值设置为新值:

setPath 
  (['foo',1,'baz'])
  ("new result")
  ({foo: [{bar: {qux: 3}},{bar: {qux: 5}}],corge: 8})

//=> {foo: [{bar: {qux: 3}},{bar: {qux: 5,baz: "new result"}}],corge: 8}
//                                          ^^^^^^^^^^^^^^^^^ 

(这里整数代表数组索引,字符串代表对象键。)

然后将您的输入结构转换为路径值对象数组,然后通过调用 reduce 对目标数组中的每个对象进行 setPath-ing,这很简单。

const setPath = ([p,...ps]) => (v) => (o) =>
  p == undefined ? v : Object .assign (
    Array .isArray (o) || Number .isInteger (p) ? [] : {},{...o,[p]: setPath (ps) (v) ((o || {}) [p])}
  )

const nest = (o) =>
  Object .entries (o) .map (
    ([k,v]) => [k .split ('.') .map (Number),v]
  ) .reduce ((a,[p,v]) => setPath (p) ([[v]]) (a),[]) .slice (1)

const numberedList = {"1": "Text of 1","1.2": {key: "object of 1.2"},"1.2.2": function () {return "function of 1.2.2";},"2": 2}

console .log (nest (numberedList))
.as-console-wrapper {max-height: 100% !important; top: 0}

这不是您要求的输出。但我对那个输出没有多大意义。您可能需要稍微调整一下才能完全按照您的需要进行。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。