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

I am getting following data from multiple source. In those object there is a field PID which one is common. So , I want to combined it according to PID.

Expected output :

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

I tried with following

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

But I am not getting what I expected. then I tried with How to group array of objects by key But My source is 3 not 1.

5
  • Possible duplicate of How to group array of objects by key Commented Sep 28, 2017 at 10:38
  • var result = sourceA.map((obj, index) => Object.assign({}, sourceA[index], sourceB[index], sourceC[index])); Commented Sep 28, 2017 at 10:39
  • When someone requests for more information, please add this information in question. Comments can get collapsed. Commented Sep 28, 2017 at 10:40
  • @Sharat did any of the solutions solve your issue? Commented Sep 29, 2017 at 12:37
  • Just fixed it. Thanks everyone. Commented Sep 29, 2017 at 12:43

4 Answers 4

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

As it is not clear from your question were from we could get "33" and "30" values i assume you made a typo, and expected result should be like this:

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

considering the above you may try to use few loops to group data by pid and then format it as expected

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

Result should look like expected. Probably this is not the best solution, but it works

Sign up to request clarification or add additional context in comments.

Comments

2

If the data is always structured as an object like:

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

we can do the following:

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]));

One advantage to this method is it works for any number of pid and data_N properties.

The result is:

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

Comments

1

I used a Map as temporary structure:

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

Comments

1

Try this:

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.