【问题标题】:How to simplify conversion of nested object into array of objects?如何简化嵌套对象到对象数组的转换?
【发布时间】:2019-02-23 13:43:13
【问题描述】:

这是我的嵌套对象

var arr = [{
    "children": [{
        "children": [{
            "children": [],
            "Id": 1,
            "Name": "A",
            "Image": "http://imgUrl"
        }],
        "Id": 2
        "Name": "B",
        "Image": "http://imgUrl"
    }],
    "Id":3,
    "Name": "C",
    "Image": "http://imgUrl"
}]

我想把上面的转换成下面的格式

[{
    "Name": "C",
    "Id": 3,
    "Image": "http://imgUrl"
}, {
    "Name": "B",
    "Id": 2,
    "Image": "http://imgUrl"
}, {
    "Name": "A",
    "Id": 1,
    "Image": "http://imgUrl"
}]

我写了下面的代码来做到这一点

    var newArr = []
    function getNestedObj(obj){

        if(obj.length){
            for ( var i=0; i<obj.length; i++){
                var newObj = {};
                newObj.Name = obj[i].Name;
                newObj.Id = obj[i].Id;
                newObj.Image = obj[i].Image;
                newArr.push(newObj);

                if(obj[i].children.length !=0 ){
                    getNestedObj(obj[i].children)
                }
                else {
                    return newArr;
                }
        }
       }
    }

我想简化上面的功能?我怎样才能做到这一点?

【问题讨论】:

  • 现在您的代码按预期工作了吗?或者它给出了一些错误或意外的结果?如果它工作,也许你应该去codereview.stackexchange.com询问
  • @ramya-selvaraj 你在“Id”后面少了一个逗号: 2. 我不能编辑它,因为编辑需要至少 6 个字符。
  • @JasperZelf 谢谢,我现在编辑:)

标签: javascript arrays json object


【解决方案1】:

尝试关注

let arr = [{"children":[{"children":[{"children":[],"Id":1,"Name":"A","Image":"http://imgUrl"}],"Id":2,"Name":"B","Image":"http://imgUrl"}],"Id":3,"Name":"C","Image":"http://imgUrl"}];

function fillWithChildren(a, r=[]) {
  a.forEach(({children, ...rest}) => {
    r.push(rest);
    if(children) fillWithChildren(children, r);
  });
  return r;
}
let result = fillWithChildren(arr);
console.log(result);

【讨论】:

【解决方案2】:

递归归约:

const fillWithChildren = (a = []) =>
a.reduce(
    (result, { children, ...rest }) =>
        result
            .concat(rest)
            .concat(fillWithChildren(children)),
    [],
);
fillWithChildren(arr);

【讨论】:

  • 编辑了我的答案:设置一个默认值,不再需要三元。
【解决方案3】:

这可以像递归减少一样简单。

arr.reduce (function spr (res, cur) {
    let obj = {...cur}
    let children = obj.children
    delete obj.children;
    return children.reduce (spr, res).concat ([{
        ...obj
    }])
}, [])

let result = arr.reduce (function spr (res, cur) {
    let obj = {...cur}
    let children = obj.children;
    delete obj.children;
    return children.reduce (spr, res).concat ([{
      	...obj
    }])
}, [])

console.log (result)
<script>
var arr = [{
    "children": [{
        "children": [{
            "children": [{
                "children": [],
                "Id": 1,
                "Name": "A",
                "Image": "http://imgUrl"
            }],
            "Id": 1,
            "Name": "A",
            "Image": "http://imgUrl"
        }],
        "Id": 2,
        "Name": "B",
        "Image": "http://imgUrl"
    }],
    "Id":3,
    "Name": "C",
    "Image": "http://imgUrl"
}
, {
    "children": [{
        "children": [{
            "children": [],
            "Id": 1,
            "Name": "A",
            "Image": "http://imgUrl"
        }],
        "Id": 2,
        "Name": "B",
        "Image": "http://imgUrl"
    }],
    "Id":3,
    "Name": "C",
    "Image": "http://imgUrl"
}]
</script>

【讨论】:

  • @StephanHovius 是的,是吗? sprreduce使用的函数,看children.reduce (spr,...)这行,就是递归调用。
  • 是的,我错过了。如果你使用传播,你可以使用默认的休息传播来缩短它:arr.reduce(function spr(res, { children = [], ...rest }) { return children.reduce(spr, res).concat(rest); }, [])
猜你喜欢
  • 1970-01-01
  • 2020-05-03
  • 2021-05-28
  • 2020-07-03
  • 2019-04-26
  • 2018-01-04
  • 1970-01-01
  • 2020-07-07
  • 1970-01-01
相关资源
最近更新 更多