Javascript 使用lodash.groupBy()对对象进行法线化
我有一个由三个不同对象组成的非规范化数组-Javascript 使用lodash.groupBy()对对象进行法线化,javascript,lodash,ramda.js,Javascript,Lodash,Ramda.js,我有一个由三个不同对象组成的非规范化数组-国家、学校、学生 const input= [ { countryID: 12, country: "US", schoolID: 122, schoolZone: "Highlands", studentID: 142, studentName: "Mary" }, { countryID: 12, country: "US",
国家、学校、学生
const input=
[
{
countryID: 12,
country: "US",
schoolID: 122,
schoolZone: "Highlands",
studentID: 142,
studentName: "Mary"
},
{
countryID: 12,
country: "US",
schoolID: 122,
schoolZone: "Highlands",
studentID: 145,
studentName: "John"
},
{
countryID: 14,
country: "UK",
schoolID: 222,
schoolZone: "Leeds",
studentID: 223,
studentName: "Peter"
}
];
我想像这样使他们正常化
const result=
[
{
countryID: 12,
country: "US",
schools: [
{
schoolID: 122,
schoolZone: "Highlands",
students: [
{
studentID: 142,
studentName: "Mary"
},
{
studentID: 145,
studentName: "John"
}
]
}
]
},
{
countryID: 14,
country: "UK",
schools: [
{
schoolID: 222,
schoolZone: "Leeds",
students: [
{
studentID: 223,
studentName: "Peter"
}
]
}
]
}
];
我知道lodash
和ramda
可用于实现嵌套归一化
但我对这两个图书馆都不熟悉
你能帮我实现一下吗?考虑到
学校
和学生
的嵌套,还想知道咖喱是否会是一个考虑因素,首先将每个对象重塑为最终的数据结构:
reshape({
countryID: 12,
country: "US",
schoolID: 122,
schoolZone: "Highlands",
studentID: 142,
studentName: "Mary" });
//=> {
//=> country: "US",
//=> countryID: 12,
//=> schools: [
//=> {
//=> schoolID: 122,
//=> schoolZone: "Highlands",
//=> students: [
//=> {
//=> studentID: 142,
//=> studentName: "Mary"
//=> }
//=> ]
//=> }
//=> ]
//=> }
然后,只需按国家分组,然后按学校分组,并使用map&reduce函数合并对象
const{pick,map,groupBy,values,lensProp,over,reduce,mergeWithKey,pipe,prop,applySpec,converge,set,of}=R;
常量输入=[
{countryID:12,
国家:“美国”,
学号:122,
学区:“高地”,
学号:142,,
学生姓名:“玛丽”},
{countryID:12,
国家:“美国”,
学号:122,
学区:“高地”,
学号:145,,
学生姓名:“约翰”},
{countryID:14,
国家:“英国”,
学号:222,
校园:“利兹”,
学号:223,
学生姓名:“彼得”}];
常数重塑=applySpec({
countryID:prop('countryID'),
国家:道具(“国家”),
学校:汇聚(
管道(一套(lensProp(“学生”),共套)[
管道(拾取(['studentID','studentName']),共,
选择(['schoolID','schoolZone']))
});
const mergeArrays=key=>mergeWithKey((k,a,b)=>k==key?[a[0],b[0]]:a);
const groupStudents=管道(
groupBy(道具(“学校ID”),
价值观
map(reduce(mergearray('students'),{}));
const进程=管道(
映射(重塑),
groupBy(prop('countryID')),
map(reduce(合并数组('schools'),{})),
地图(在(lensProp(“学校”),学生组)上方),
价值观);
console.log(进程(输入))代码>
首先重塑每个对象,使其看起来像最终的数据结构:
reshape({
countryID: 12,
country: "US",
schoolID: 122,
schoolZone: "Highlands",
studentID: 142,
studentName: "Mary" });
//=> {
//=> country: "US",
//=> countryID: 12,
//=> schools: [
//=> {
//=> schoolID: 122,
//=> schoolZone: "Highlands",
//=> students: [
//=> {
//=> studentID: 142,
//=> studentName: "Mary"
//=> }
//=> ]
//=> }
//=> ]
//=> }
然后,只需按国家分组,然后按学校分组,并使用map&reduce函数合并对象
const{pick,map,groupBy,values,lensProp,over,reduce,mergeWithKey,pipe,prop,applySpec,converge,set,of}=R;
常量输入=[
{countryID:12,
国家:“美国”,
学号:122,
学区:“高地”,
学号:142,,
学生姓名:“玛丽”},
{countryID:12,
国家:“美国”,
学号:122,
学区:“高地”,
学号:145,,
学生姓名:“约翰”},
{countryID:14,
国家:“英国”,
学号:222,
校园:“利兹”,
学号:223,
学生姓名:“彼得”}];
常数重塑=applySpec({
countryID:prop('countryID'),
国家:道具(“国家”),
学校:汇聚(
管道(一套(lensProp(“学生”),共套)[
管道(拾取(['studentID','studentName']),共,
选择(['schoolID','schoolZone']))
});
const mergeArrays=key=>mergeWithKey((k,a,b)=>k==key?[a[0],b[0]]:a);
const groupStudents=管道(
groupBy(道具(“学校ID”),
价值观
map(reduce(mergearray('students'),{}));
const进程=管道(
映射(重塑),
groupBy(prop('countryID')),
map(reduce(合并数组('schools'),{})),
地图(在(lensProp(“学校”),学生组)上方),
价值观);
console.log(进程(输入))代码>
不使用lodash或ramda的方法可能是这样的。希望这有帮助
const输入=[{
国号:12,,
国家:“美国”,
学号:122,
学区:“高地”,
学号:142,,
学生姓名:“玛丽”
}, {
国号:12,,
国家:“美国”,
学号:122,
学区:“高地”,
学号:145,,
学生姓名:“约翰”
}, {
国号:14,,
国家:“英国”,
学号:222,
校园:“利兹”,
学号:223,
学生姓名:“彼得”
}];
常量规范化=(数据)=>
数据.reduce((acc,{studentID,studentName,schoolID,schoolZone,countryID,country})=>{
const studentToAdd={studentID,studentName};
const schoolToAdd={schoolID,schoolZone,students:[studentToAdd]};
const countryToAdd={countryID,country,schools:[schoolToAdd]};
const existingCountry=acc.find(item=>item.countryID==countryID);
如果(现有国家){
const existingSchool=existingCountry.schools.find(item=>item.schoolID==schoolID);
如果(现有学校){
const existingStudent=existingSchool.students.find(item=>item.studentID==studentID);
如果(!existingStudent)existingSchool.student.push(studentToAdd);
}
其他现有国家。学校。推(学校添加);
}
其他附件推送(国家/地区添加);
返回acc;
}, []);
日志(规范化(输入))代码>不使用lodash或ramda的方法可能是这样的。希望这有帮助
const输入=[{
国号:12,,
国家:“美国”,
学号:122,
学区:“高地”,
学号:142,,
学生姓名:“玛丽”
}, {
国号:12,,
国家:“美国”,
学号:122,
学区:“高地”,
学号:145,,
学生姓名:“约翰”
}, {
国号:14,,
国家:“英国”,
学号:222,
校园:“利兹”,
学号:223,
学生姓名:“彼得”
}];
常量规范化=(数据)=>
数据.reduce((acc,{studentID,studentName,schoolID,schoolZone,countryID,country})=>{
const studentToAdd={studentID,studentName};
const schoolToAdd={schoolID,schoolZone,students:[studentToAdd]};
const countryToAdd={countryID,country,schools:[schoolToAdd]};
const existingCountry=acc.find(item=>item.countryID==countryID);
如果(现有国家){
const existingSchool=existingCountry.schools.find(item=>item.schoolID==schoolID);
如果(现有学校){
const existingStudent=existingSchool.students.find(item=>item.studentID==st