Merging linked Data in Array in Javascript

a 夏天 提交于 2020-01-15 10:06:50

问题


I have a simple task of rearranging a couple of Arrays in a JSON, so ractive.js can handle it better. But I got carried away a bit, and the outcome was not particularly satisfactory.

An example of my initial Array:

[{
  "_id": 1,
  "type": "person",
  "Name": "Hans",
  "WorksFor": ["3", "4"],
}, {
  "_id": 2,
  "type": "person",
  "Name": "Michael",
  "WorksFor": ["3"],
}, {
  "_id": 3,
  "type": "department",
  "Name": "Marketing"
}, {
  "_id": 4,
  "type": "department",
  "Name": "Sales"
}, {
  "_id": 5,
  "type": "person",
  "Name": "Chris",
  "WorksFor": [],
}]

So with a given Department I wanted a method in ractive to give me all Persons who work in this Department (with a list of Departments they work for). Something like:

[{
  "_id": 1,
  "type": "person",
  "Name": "Hans",
  "WorksFor": ["3", "4"],
  "Readable": ["Marketing", "Sales"]
}, {
  "_id": 2,
  "type": "person",
  "Name": "Michael",
  "WorksFor": ["3"],
  "Readable": ["Sales"]
}]

The function that somehow came to life was similar to this:

function imsorryforthis() {
  let output = [];
  let tempdocs = this.get('docs'); //as this happens in a ractive method, 
//"this.get" is neccesary for binding 
  for (var i = 0; i < tempdocs.length; i++) {
    if (_.contains(tempdocs[i].WorksFor, givenDepartment)) { //I used underscore.js here
      let collectedDepartmentData = [];
      if (tempdocs[i].WorksFor.length > 0) {
        for (var f = 0; f < tempdocs[i].WorksFor.length; f++) {
          for (var g = 0; g < tempdocs.length; g++) {
            if (tempdocs[i].WorksFor[f] == tempdocs[g]._id) {
              let actualDepartmentData = {};
              actualDepartmentData = tempdocs[g];
              collectedDepartmentData.push(actualDepartmentData);
            }
          }
        }
      }
      tempdocs[i].Readable = collectedDepartmentData;
      output.push(tempdocs[i]);
    }
  }
  return output;
}

I've put it in a Fiddle as well to make it better readable.

Due to the fact that somehow this monstrosity does work (I was astonished myself), it feels like scratching your left ear with your right hand over your head (while being constantly shouted at by a group of desperate mathematicians).

Maybe anybody knows a more presentable and smarter approach (or a way to compile JavaScript so this never sees the light of day again).


回答1:


Construct a map department_id => department_name first:

let departments = {};

for (let x of data) {
    if (x.type === 'department') {
        departments[x._id] = x.Name;
    }
}

Then, iterate over Persons and populate Readable arrays from that map:

for (let x of data) {
    if (x.type === 'person') {
        x.Readable = x.WorksFor.map(w => departments[w]);
    }
}

Finally, extract Persons for the specific Department:

personsInSales = data.filter(x => 
    x.type === 'person' && x.WorksFor.includes('3'));



回答2:


Firstly, your data structure does not have a good design. You should not be returning person and department in the same array. If possible, try to redesign the initial data structure to make it more modular, by separating out the people and department into separate structures. However if you are stuck with this same data structure, you can write the code a little better. Please find the code below. Hope it helps!

function mapPeopleDepartment() {
    var deptMap = {},peopleList = [];
    //Iterate through the initialArray and separate out the department into a hashmap deptMap and people into a new peopleList
    for(var i=0; i < initArray.length; i++) {
        var obj = initArray[i];
        obj.type == "department" ? deptMap[obj._id] = obj.Name :  peopleList.push(obj);
     }
    //Iterate through the peopleList to map the WorksFor array to a Readable array
    for(var i=0; i < peopleList.length; i++) {
       var person = peopleList[i];
       person.Readable = _.map(person.WorksFor, function(dept){return deptMap[dept]});
    }
    return peopleList;
}


来源:https://stackoverflow.com/questions/41666909/merging-linked-data-in-array-in-javascript

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!