JS:将数组简化为嵌套对象 [英] JS: Reduce array to nested objects
问题描述
所以我有这个数组
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屋!