在Javascript中合并数组中的链接数据

时间:2017-01-15 22:14:03

标签: javascript arrays ractivejs

我有一个简单的任务,即在JSON中重新排列几个数组,因此ractive.js可以更好地处理它。但是我被带走了一些,结果并不是特别令人满意。

我的初始数组的一个例子:

[{
  "_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": [],
}]

因此,在一个特定的部门,我想要一个ractive方法给我所有在该部门工作的人员(他们为他们工作的部门列表)。类似的东西:

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

以某种方式生活的功能与此相似:

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

我也将它放在Fiddle中以使其更易读。

由于这种怪物不知何故确实起作用(我自己感到惊讶),感觉就像是用右手捂住你的左耳(同时被一群绝望的数学家不断喊叫)。

也许任何人都知道一种更明显更智能的方法(或者一种编译JavaScript的方法,所以这种方法再也看不到它了。)

2 个答案:

答案 0 :(得分:1)

首先,您的数据结构没有良好的设计。你不应该在同一个数组中返回人员和部门。如果可能,尝试重新设计初始数据结构,使其更加模块化,将人员和部门分离为单独的结构。但是,如果您坚持使用相同的数据结构,则可以更好地编写代码。请在下面找到代码。希望能帮助到你!

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

答案 1 :(得分:1)

首先构建地图department_id => department_name

let departments = {};

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

然后,迭代人员并从该地图填充Readable数组:

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

最后,为特定部门提取人员:

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