JS:将数组简化为嵌套对象 [英] JS: Reduce array to nested objects

查看:90
本文介绍了JS:将数组简化为嵌套对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我有这个数组

var mapped = [[2016, "October", "Monday", {object}], [2017, "January", "Friday", {object}], [2017, "January", "Wednesday", {object}], [2017, "October", "Monday", {object}]]

我想要完成的事情是这样的:

[{
    "2016": [{
        "October": [{
            "Monday": [{object}]
        }]
    }],
}, {
    "2017": [{
        "January": [{
            "Friday": [{object}]
        }, {
            "Wednesday": [{object}]
        }]
    }, {
        "October": [{
            "Monday": [{object}]
        }]
    }]
}]

我已经搜索了很长时间,但是找不到解决方案.通过使用reduce,我得到的是这样的东西:

[
    2016: [{
        "month": "October"
    }]
],
[
    2017: [{
        "month": "January"
    },
    {
        "month": "January"
    },
    {
        "month": "September"
    }]
]

所以我好像很迷恋,但是还很遥远……这就是我在做的事情:

mapped.reduce((years, array) => {

                    years[array[0]] = years[array[0]] || [];

                    years[array[0]].push({
                        month: array[1]
                    })

                    return years;

                }, [])

解决方案

不完全是您指定的内容,但是我认为以下脚本输出的格式将是最有用的-它只会在最深层生成数组:

 const  mapped = [[2016, "October", "Monday", { a: 1 }], [2017, "January", "Friday", { a: 1 }], [2017, "January", "Wednesday", { a: 1 }], [2017, "October", "Monday", { a: 1 }]];
   
const result = mapped.reduce( (acc, [year, month, day, object]) => {
    let curr = acc[year] = acc[year] || {};
    curr = curr[month] = curr[month] || {};
    curr = curr[day] = curr[day] || [];
    curr.push(object);
    return acc;
}, {});

console.log(result);
    

 .as-console-wrapper { max-height: 100% !important; top: 0; } 

使用数组换行

如果您确实需要包装数组,则可以对先前的结果应用额外的递归函数:

 const  mapped = [[2016, "October", "Monday", { a: 1 }], [2017, "January", "Friday", { a: 1 }], [2017, "January", "Wednesday", { a: 1 }], [2017, "October", "Monday", { a: 1 }]];
   
const result = mapped.reduce( (acc, [year, month, day, object]) => {
    let curr = acc[year] = acc[year] || {};
    curr = curr[month] = curr[month] || {};
    curr = curr[day] = curr[day] || [];
    curr.push(object);
    return acc;
}, {});

function wrapInArrays(data) {
    return Array.isArray(data) ? data 
        : Object.entries(data).map ( ([key, value]) => {
            return { [key]: wrapInArrays(value) };
        });
}

const wrapped = wrapInArrays(result);
console.log(wrapped); 

 .as-console-wrapper { max-height: 100% !important; top: 0; } 

So I have this array

var mapped = [[2016, "October", "Monday", {object}], [2017, "January", "Friday", {object}], [2017, "January", "Wednesday", {object}], [2017, "October", "Monday", {object}]]

What I want to accomplish is something like this:

[{
    "2016": [{
        "October": [{
            "Monday": [{object}]
        }]
    }],
}, {
    "2017": [{
        "January": [{
            "Friday": [{object}]
        }, {
            "Wednesday": [{object}]
        }]
    }, {
        "October": [{
            "Monday": [{object}]
        }]
    }]
}]

I've been searching around for so long, and I can't find a solution.. By using reduce, I'm getting something like this:

[
    2016: [{
        "month": "October"
    }]
],
[
    2017: [{
        "month": "January"
    },
    {
        "month": "January"
    },
    {
        "month": "September"
    }]
]

So it seems like I'm into something, but still so far away... This is what I'm doing:

mapped.reduce((years, array) => {

                    years[array[0]] = years[array[0]] || [];

                    years[array[0]].push({
                        month: array[1]
                    })

                    return years;

                }, [])

解决方案

Not exactly what you specified, but I feel the following script outputs a format that will be most useful -- it only produces arrays at the deepest level:

const  mapped = [[2016, "October", "Monday", { a: 1 }], [2017, "January", "Friday", { a: 1 }], [2017, "January", "Wednesday", { a: 1 }], [2017, "October", "Monday", { a: 1 }]];
   
const result = mapped.reduce( (acc, [year, month, day, object]) => {
    let curr = acc[year] = acc[year] || {};
    curr = curr[month] = curr[month] || {};
    curr = curr[day] = curr[day] || [];
    curr.push(object);
    return acc;
}, {});

console.log(result);
   

.as-console-wrapper { max-height: 100% !important; top: 0; }

With array wrapping

If you really need the wrapping arrays, you can apply an extra recursive function to the previous result:

const  mapped = [[2016, "October", "Monday", { a: 1 }], [2017, "January", "Friday", { a: 1 }], [2017, "January", "Wednesday", { a: 1 }], [2017, "October", "Monday", { a: 1 }]];
   
const result = mapped.reduce( (acc, [year, month, day, object]) => {
    let curr = acc[year] = acc[year] || {};
    curr = curr[month] = curr[month] || {};
    curr = curr[day] = curr[day] || [];
    curr.push(object);
    return acc;
}, {});

function wrapInArrays(data) {
    return Array.isArray(data) ? data 
        : Object.entries(data).map ( ([key, value]) => {
            return { [key]: wrapInArrays(value) };
        });
}

const wrapped = wrapInArrays(result);
console.log(wrapped);

.as-console-wrapper { max-height: 100% !important; top: 0; }

这篇关于JS:将数组简化为嵌套对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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