JavaScript 将平面数组转换为嵌套/分组和排序数组
JavaScript transform flat array to nested / grouped and sorted array
我正在尝试将对象数组转换为 'grouped' 并在 JavaScript 中排序输出数组 ,最好是 ES6 方式(例如使用.map
、.reduce
等)。
总结:
- 对象数组
- 每个对象都是一个 'item':a1,a2,b1,b2,...
- 每个对象都有一个 'section' 属性 就像 group/category
- 所需的输出数组应该 return 按 'section'
分组的项目对象
- 节和项的输出数组的排序顺序也在 属性 中定义
const data = [
{ section: 'A', item: 'a1', section_order: 2, item_order: 2 },
{ section: 'B', item: 'b1', section_order: 1, item_order: 2 },
{ section: 'A', item: 'a2', section_order: 2, item_order: 1 },
{ section: 'B', item: 'b2', section_order: 1, item_order: 1 }
];
const desiredOutput = [
{
section: 'B', // should come first as section_order = 1
items: [
{ section: 'B', item: 'b2', section_order: 1, item_order: 1 }, // should come first as item_order = 1
{ section: 'B', item: 'b1', section_order: 1, item_order: 2 }, // should come second as item_order = 2
]
},
{
section: 'A', // should come second as section_order = 2
items: [
{ section: 'A', item: 'a2', section_order: 2, item_order: 1 },
{ section: 'A', item: 'a1', section_order: 2, item_order: 2 },
]
}
];
我看到了一个让我朝着正确方向前进的例子——但不完全是我想要的输出,也没有满足排序顺序:
const result = data.reduce((accum, currElm) => {
const currSection = currElm['section'];
accum[currSection] = (accum[currSection] || []).concat(currElm);
return accum;
}, {});
您应该先 sort
您的数据。 sort
函数看起来像这样
data.sort((a, b) => (a.section_order - b.section_order) || (a.item_order - b.item_order));
如您所见,我们将条件分为两部分:
(a.section_order - b.section_order)
(a.item_order - b.item_order)
意思是先排序section_order
再排序item_order
.
在那之后,您可以使用 dictionary power 只循环一次,如下所示
const data = [
{ section: 'A', item: 'a1', section_order: 2, item_order: 2 },
{ section: 'B', item: 'b1', section_order: 1, item_order: 2 },
{ section: 'A', item: 'a2', section_order: 2, item_order: 1 },
{ section: 'B', item: 'b2', section_order: 1, item_order: 1 }
];
data.sort((a, b) => (a.section_order - b.section_order) || (a.item_order - b.item_order));
var result = [];
for(var item of data){
var section = item.section;
if(!result[section]){ // if not exists => create new
result[section] = { section, items:[item] };
}else{ // if exists => add one more item into items
result[section].items.push(item);
}
}
console.log(Object.values(result));
旧版本使用reduce & map
const data = [
{ section: 'A', item: 'a1', section_order: 2, item_order: 2 },
{ section: 'B', item: 'b1', section_order: 1, item_order: 2 },
{ section: 'A', item: 'a2', section_order: 2, item_order: 1 },
{ section: 'B', item: 'b2', section_order: 1, item_order: 1 }
];
data.sort((a, b) => (a.section_order - b.section_order) || (a.item_order - b.item_order));
const accumData = data.reduce((accum, currElm) => {
const currSection = currElm['section'];
accum[currSection] = (accum[currSection] || []).concat(currElm);
return accum;
}, {});
var result = Object.entries(accumData).map(([key, value]) => ({section: key, items: value}));
console.log(result);
我正在尝试将对象数组转换为 'grouped' 并在 JavaScript 中排序输出数组 ,最好是 ES6 方式(例如使用.map
、.reduce
等)。
总结:
- 对象数组
- 每个对象都是一个 'item':a1,a2,b1,b2,...
- 每个对象都有一个 'section' 属性 就像 group/category
- 所需的输出数组应该 return 按 'section' 分组的项目对象
- 节和项的输出数组的排序顺序也在 属性 中定义
const data = [
{ section: 'A', item: 'a1', section_order: 2, item_order: 2 },
{ section: 'B', item: 'b1', section_order: 1, item_order: 2 },
{ section: 'A', item: 'a2', section_order: 2, item_order: 1 },
{ section: 'B', item: 'b2', section_order: 1, item_order: 1 }
];
const desiredOutput = [
{
section: 'B', // should come first as section_order = 1
items: [
{ section: 'B', item: 'b2', section_order: 1, item_order: 1 }, // should come first as item_order = 1
{ section: 'B', item: 'b1', section_order: 1, item_order: 2 }, // should come second as item_order = 2
]
},
{
section: 'A', // should come second as section_order = 2
items: [
{ section: 'A', item: 'a2', section_order: 2, item_order: 1 },
{ section: 'A', item: 'a1', section_order: 2, item_order: 2 },
]
}
];
我看到了一个让我朝着正确方向前进的例子——但不完全是我想要的输出,也没有满足排序顺序:
const result = data.reduce((accum, currElm) => {
const currSection = currElm['section'];
accum[currSection] = (accum[currSection] || []).concat(currElm);
return accum;
}, {});
您应该先 sort
您的数据。 sort
函数看起来像这样
data.sort((a, b) => (a.section_order - b.section_order) || (a.item_order - b.item_order));
如您所见,我们将条件分为两部分:
(a.section_order - b.section_order)
(a.item_order - b.item_order)
意思是先排序section_order
再排序item_order
.
在那之后,您可以使用 dictionary power 只循环一次,如下所示
const data = [
{ section: 'A', item: 'a1', section_order: 2, item_order: 2 },
{ section: 'B', item: 'b1', section_order: 1, item_order: 2 },
{ section: 'A', item: 'a2', section_order: 2, item_order: 1 },
{ section: 'B', item: 'b2', section_order: 1, item_order: 1 }
];
data.sort((a, b) => (a.section_order - b.section_order) || (a.item_order - b.item_order));
var result = [];
for(var item of data){
var section = item.section;
if(!result[section]){ // if not exists => create new
result[section] = { section, items:[item] };
}else{ // if exists => add one more item into items
result[section].items.push(item);
}
}
console.log(Object.values(result));
旧版本使用reduce & map
const data = [
{ section: 'A', item: 'a1', section_order: 2, item_order: 2 },
{ section: 'B', item: 'b1', section_order: 1, item_order: 2 },
{ section: 'A', item: 'a2', section_order: 2, item_order: 1 },
{ section: 'B', item: 'b2', section_order: 1, item_order: 1 }
];
data.sort((a, b) => (a.section_order - b.section_order) || (a.item_order - b.item_order));
const accumData = data.reduce((accum, currElm) => {
const currSection = currElm['section'];
accum[currSection] = (accum[currSection] || []).concat(currElm);
return accum;
}, {});
var result = Object.entries(accumData).map(([key, value]) => ({section: key, items: value}));
console.log(result);