javascript - Javascript对象数组重组
问题描述
我正在从已加入 3 个表的关系数据库中获取数据:
var btnObj2 = [
{sect_id: 1, sect_title: 'Navigation', subsect_id: 1, subsect_title:'Übersicht', btn_id: 1, btn_title: 'Inhaltsverzeichnis'},
{sect_id: 1, sect_title: 'Navigation', subsect_id: 1, subsect_title: 'Übersicht', btn_id: 2, btn_title: 'Stichwortverzeichnis'},
{sect_id: 1, sect_title: 'Navigation', subsect_id: 2, subsect_title: 'Praxisphasen', btn_id: 3, btn_title: 'Trainingserfolg'},
{sect_id: 1, sect_title: 'Navigation', subsect_id: 2, subsect_title: 'Praxisphasen', btn_id: 4, btn_title: 'Trainingsablauf'},
{sect_id: 2, sect_title: 'Modul 1', subsect_id: 3, subsect_title: 'Mentor-Gespräche', btn_id: 5, btn_title: 'Lebenszeit'},
{sect_id: 2, sect_title: 'Modul 1', subsect_id: 3, subsect_title: 'Mentor-Gespräche', btn_id: 6, btn_title: 'Lebensplanung'},
{sect_id: 2, sect_title: 'Modul 1', subsect_id: 4, subsect_title: 'Just do it', btn_id: 7, btn_title: 'Vertrauen'},
{sect_id: 2, sect_title: 'Modul 1', subsect_id: 4, subsect_title: 'Just do it', btn_id: 8, btn_title: 'Verantwortung'}
];
必须重新构建此数据,以便每个部分都包含其子部分,并且每个子部分包含其子子子部分(子子子部分是上面代码片段中的按钮)。数据库中的数据已经按照section、sub-section、subsub-section以正确的顺序返回。
输出必须如下:
var result = [
{
sect_id: 1,
sect_title: 'Navigation',
subsect: [
{
subsect_id: 1,
subsect_title: 'Übersicht',
buttons: [
{
btn_id: 1,
btn_title: 'Verantwortung'
},
{
btn_id: 2,
btn_title: 'Vertrauen'
}
]
},
{
subsect_id: 2,
subsect_title: 'Praxisphasen',
buttons: [
{
btn_id: 3,
btn_title: 'Trainingserfolg'
},
{
btn_id: 4,
btn_title: 'Trainingsablauf'
}
]
}
]
},
sect_id: 2,
sect_title: 'Module 1',
//.....
];
这是我将以 PHP 方式执行的操作:
function prepareBtns(arr) {
var sectId, subsectId = ''
var newArr = []
arr.forEach((item) => {
if(sectId !== item.sect_id){
sectId = item.sect_id
}
if(subsectId !== item.subsect_id){
subsectId = item.subsect_id
}
//In PHP the following line does the Job
newArr[sectId][subsectId][] = item
})
return newArr
}
这是我的 JS 试验之一。这导致空槽:
function prepareBtnsXY(arr) {
var newArr = [];
arr.forEach((item) => {
if (!newArr[item.sect_id]) {
var objToPush = {
sectId: item.sect_id,
sectName: item.sect_title,
subsect: []
};
newArr[item.sect_id] = objToPush;
}
if (!newArr[item.sect_id].subsect[item.subsect_id]) {
var subObjToPush = {
subsectId: item.subsect_id,
subsectName: item.subsect_title,
buttons: []
};
newArr[item.sect_id].subsect[item.subsect_id] = subObjToPush;
}
if (!newArr[item.sect_id].subsect[item.subsect_id].buttons[item.btn_id]) {
var btnObjToPush = {
btnId: item.btn_id,
btnName: item.btn_title
};
newArr[item.sect_id].subsect[item.subsect_id].buttons[item.btn_id] = btnObjToPush;
}
});
return newArr
}
解决方案
您可以将所需的键存储在另一个数组中,其中每行的第一个键是分组的键值,以下键是此级别的数据键,最后一个键是子级/子级。最终数组不包含 children 值,而是undefined
.
keys = [ // level key level properties children // ------------ ----------------------------- ---------- ['sect_id', 'sect_title' /* more keys */, 'subsect'], ['subsect_id', 'subsect_title', 'buttons'], ['btn_id', 'btn_title', undefined] ],
该算法通过获取实际数组并搜索相同的分组键和值来迭代数据并减少键。如果未找到,它将使用给定的键生成一个新级别并将其推送到数组并返回子数组以用于下一个级别。
这种方法的优点是,只需更改原始数据和相应的keys
数组即可轻松维护,该数组充当分组规则集。
var data = [{ sect_id: 1, sect_title: 'Navigation', subsect_id: 1, subsect_title: 'Übersicht', btn_id: 1, btn_title: 'Inhaltsverzeichnis' }, { sect_id: 1, sect_title: 'Navigation', subsect_id: 1, subsect_title: 'Übersicht', btn_id: 2, btn_title: 'Stichwortverzeichnis' }, { sect_id: 1, sect_title: 'Navigation', subsect_id: 2, subsect_title: 'Praxisphasen', btn_id: 3, btn_title: 'Trainingserfolg' }, { sect_id: 1, sect_title: 'Navigation', subsect_id: 2, subsect_title: 'Praxisphasen', btn_id: 4, btn_title: 'Trainingsablauf' }, { sect_id: 2, sect_title: 'Modul 1', subsect_id: 3, subsect_title: 'Mentor-Gespräche', btn_id: 5, btn_title: 'Lebenszeit' }, { sect_id: 2, sect_title: 'Modul 1', subsect_id: 3, subsect_title: 'Mentor-Gespräche', btn_id: 6, btn_title: 'Lebensplanung' }, { sect_id: 2, sect_title: 'Modul 1', subsect_id: 4, subsect_title: 'Just do it', btn_id: 7, btn_title: 'Vertrauen' }, { sect_id: 2, sect_title: 'Modul 1', subsect_id: 4, subsect_title: 'Just do it', btn_id: 8, btn_title: 'Verantwortung' }],
keys = [['sect_id', 'sect_title', 'subsect'], ['subsect_id', 'subsect_title', 'buttons'], ['btn_id', 'btn_title', undefined]],
result = data.reduce((r, o) => {
keys.reduce((a, k) => {
var temp = a.find(p => o[k[0]] === p[k[0]]);
if (!temp) {
a.push(temp = Object.assign(
...k.map((l, i, { length }) =>
l && { [l]: i + 1 === length ? [] : o[l] })
));
}
return temp[k[k.length - 1]];
}, r);
return r;
}, []);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
推荐阅读
- r - 如何使用 fitdist 函数(负二项式)?
- swift - I keep using this same chunk of code over and over. How do I consolidate it?
- ios - Google 助理的深层链接参数
- ios - Casting to object with Codable
- javascript - Positioning of legend in javascript
- kubernetes - 有没有办法配置 Istio 将流量路由到处于终止状态的 POD?
- c# - C#指定父类与接口之间的区别
- osgi - ServiceTrackerCustomizer 服务引用返回 null
- java - 对整数的arraylist的arrylist进行排序不取决于它们在java中的长度
- typescript - TypeScript: Any way to get a compile-time error when I redefine a variable with 'let'?