javascript - JavaScript 将平面数组转换为嵌套/分组和排序数组
问题描述
我正在尝试将对象数组转换为 JavaScript 中的“分组”和排序的输出数组,最好是 ES6 方式(例如使用.map
,.reduce
等)。
概括:
- 对象数组
- 每个对象都是一个“项目”:a1,a2,b1,b2,...
- 每个对象都有一个“部分”属性,就像一个组/类别
- 所需的输出数组应返回按“部分”分组的项目对象
- 部分和项目的输出数组的排序顺序也在属性中定义
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
。
之后,您可以使用字典功能循环一次,如下所示
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);
推荐阅读
- javascript - 如何更改 DOM 上类内的属性值?
- python - python 3中询问用户输入时如何让光标闪烁
- python - 即使不直接调用类的特殊方法,“if”是否也可以隐式访问它们?
- javascript - 如何根据 Django 中选择的语言更改我的内联样式
- mysql - information_schema 相关查询中的 MySQL 8.0.22 回归
- reactjs - 无法理解客户端路由
- python - 从 dict 获取具有最新日期时间戳的 id
- r - 创建归因模型时 R 中的 MarkovChain 包错误:错误!转换矩阵的行不是某个
- powershell - 优化 Get-ADUser 过滤器
- c# - C# DeserializeObject 的 OpenApiDocument 与 IOpenApiAny