Merging linked Data in Array in Javascript

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).

Answers:

Answer

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'));
Answer

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;
}

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.