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