如何使用Javascript在Single对象中映射多个对象数据?

时间:2017-09-28 10:35:53

标签: javascript object vuejs2

var sourceA = [{ pid: 1, data_a: 23, data_x: 23},{ pid: 2, data_a: 23 ,data_x: 23}];

var sourceB = [{ pid: 1, data_a: 34, data_x: 34 },{ pid: 2, data_a: 34, data_x: 34 }];

var sourceC = [{ pid: 1, data_a: 35, data_x: 34 },{ pid: 2, data_a: 35, data_x: 34 }];

我从多个来源获取以下数据。在那些对象中存在一个字段PID,其中一个是常见的。所以,我想根据PID结合它。

预期输出:

var p = [{
  "pid": 1,
  "array": [{"data_a": 33,"data_x": 30},{"data_a": 33,"data_x": 30},{"data_a": 33,"data_x": 30}]
},{
  "pid": 2,
  "array": [{"data_a": 33,"data_x": 30},{"data_a": 33,"data_x": 30},{"data_a": 33,"data_x": 30}]
}]

我尝试了以下

 var result = sourceA.map((obj, index) => Object.assign({}, sourceA[index], sourceB[index], sourceC[index]));

但我没有达到我的预期。然后我尝试了How to group array of objects by key 但我的来源是3而不是1。

4 个答案:

答案 0 :(得分:3)

var p = [{
  "pid": 1,
  "array": [{"data_a": 33,"data_x": 30},{"data_a": 33,"data_x": 30},{"data_a": 33,"data_x": 30}]
},{
  "pid": 2,
  "array": [{"data_a": 33,"data_x": 30},{"data_a": 33,"data_x": 30},{"data_a": 33,"data_x": 30}]
}]

由于你的问题不清楚,我们可以得到“33”和“30”的值,我认为你写了一个错字,预期的结果应该是这样的:

var p = [{
  "pid": 1,
  "array": [{"data_a": 23,"data_x": 23},{"data_a": 34,"data_x": 34},{"data_a": 35,"data_x": 34}]
},{
  "pid": 2,
  "array": [{"data_a": 23,"data_x": 23},{"data_a": 34,"data_x": 34},{"data_a": 35,"data_x": 34}]
}]

考虑到上述情况,您可以尝试使用少量循环按pid对数据进行分组,然后按预期格式化

var sourceA = [{ pid: 1, data_a: 23, data_x: 23},{ pid: 2, data_a: 23 ,data_x: 23}];
var sourceB = [{ pid: 1, data_a: 34, data_x: 34 },{ pid: 2, data_a: 34, data_x: 34 }];
var sourceC = [{ pid: 1, data_a: 35, data_x: 34 },{ pid: 2, data_a: 35, data_x: 34 }];

function combineInputs(...inputs) {

  var combined = {};
  for (var i = 0; i< inputs.length; i++) {
    for (var j = 0; j < inputs[i].length; j++) {
      var record = inputs[i][j];

      if (!combined[record.pid]) {
        combined[record.pid] = []
      }
      var tmp = Object.assign({}, record);
      delete tmp.pid;
      combined[record.pid].push(tmp);
    }
  }

  var result = [];
  for (var key in combined) {
    if (combined.hasOwnProperty(key)) {
      result.push({
        pid: key,
        array: combined[key]
      });
    }
  }

  return result;
}

var expected = combineInputs(sourceA, sourceB, sourceC);
console.log(expected);

结果看起来应该像预期的那样。可能这不是最好的解决方案,但它可以工作

答案 1 :(得分:2)

如果数据始终构造为如下对象:

{
  pid,
  data_a,
  data_b,
  ...
  data_x
}

我们可以做到以下几点:

var sourceA = [{pid: 1, data_a: 23, data_x: 23}, {pid: 2, data_a: 23, data_x: 23}];
var sourceB = [{pid: 1, data_a: 34, data_x: 34}, {pid: 2, data_a: 34, data_x: 34}];
var sourceC = [{pid: 1, data_a: 35, data_x: 34}, {pid: 2, data_a: 35, data_x: 34}];

var combineSources = function(sources) {
  var combined = sources.reduce((result, source) => {

    source.forEach(el => {
      var pid = el.pid;
      delete el.pid;

      result[pid] = result[pid] || {pid: pid, array: []}

      result[pid].array.push(el);
    });

    return result;
  }, []);

  return combined.filter(Boolean);
};

console.log(combineSources([sourceA, sourceB, sourceC]));

此方法的一个优点是适用于任意数量的piddata_N属性。

结果是:

[
  {
    "pid": 1,
    "array": [{"data_a": 23, "data_x": 23}, {"data_a": 34, "data_x": 34}, {"data_a": 35, "data_x": 34}]
  },
  {
    "pid": 2,
    "array": [{"data_a": 23,"data_x": 23}, {"data_a": 34, "data_x": 34}, {"data_a": 35, "data_x": 34}]
  }
]

答案 2 :(得分:1)

我使用Map作为临时结构:

var sourceA = [{ pid: 1, data_a: 23, data_x: 23},{ pid: 2, data_a: 23 ,data_x: 23}];

var sourceB = [{ pid: 1, data_a: 34, data_x: 34 },{ pid: 2, data_a: 34, data_x: 34 }];

var sourceC = [{ pid: 1, data_a: 35, data_x: 34 },{ pid: 2, data_a: 35, data_x: 34 }];

const myMap = new Map();

function analyzeSource(source) {
    for(obj of source) {
        if(myMap.has(obj.pid)) {
            var tmpArr = myMap.get(obj.pid);
            tmpArr.push({data_a: obj.data_a, data_x: obj.data_x});
            myMap.set(obj.pid, tmpArr);
        }
        else {
            var newArr = new Array();
            newArr.push({data_a: obj.data_a, data_x: obj.data_x});
            myMap.set(obj.pid, newArr);
        }
    }
}

analyzeSource(sourceA);
analyzeSource(sourceB);
analyzeSource(sourceC);

function fromMyMapToArr() {
    var outArr = new Array();
    for (var entry of myMap) {
        outArr.push({pid: entry[0], array: entry[1]});
    }

    return outArr;
}

var outArr = fromMyMapToArr();
console.log(outArr);

答案 3 :(得分:1)

试试这个:

    var sourceA = [{ pid: 1, data_a: 23, data_x: 23},{ pid: 2, data_a: 23 ,data_x: 23}];
    var sourceB = [{ pid: 1, data_a: 34, data_x: 34 },{ pid: 2, data_a: 34, data_x: 34 }];
    var sourceC = [{ pid: 1, data_a: 35, data_x: 34 },{ pid: 2, data_a: 35, data_x: 34 }];

    var mergedArrays = sourceA.concat(sourceB).concat(sourceC);

    Array.prototype.groupBy = function(prop) {
        return this.reduce(function(groups, item) {
            var val = item[prop];
            groups[val] = groups[val] || [];
            groups[val].push(item);
            return groups;
        }, {});
    }

    var groupByResult = mergedArrays.groupBy('pid'); 
    var result = [];
    for(pid in groupByResult){
        var obj = {};
        obj.pid = pid;
        obj.array = groupByResult[pid].map(function(obj){ delete obj.pid; return obj});
        result.push(obj);
    }
    console.log(JSON.stringify(result));