2

So, I have an indeterminate amount of arrays in an object, and I need to merge the objects in them. The arrays are guaranteed to be the same length, and the objects are guaranteed to have the same keys.

I've tried iterating through it, though for some reason, it sums the objects in every key in the array.

Example:

var demo = {
  "key1": [{"a": 4, "b": 3, "c": 2, "d": 1}, {"a": 2, "b": 3, "c": 4, "d": 5}, {"a": 1, "b": 4, "c": 2, "d": 9}]
  "key2": [{"a": 3, "b": 5, "c": 3, "d": 4}, {"a": 2, "b": 9, "c": 1, "d": 3}, {"a": 2, "b": 2, "c": 2, "d": 3}]
};

mergeArrays(demo);

/* Returns:
  {
    "arbitraryname": [{"a": 7, "b": 8, "c": 5, "d": 5}, {"a": 4, "b": 12, "c": 5, "d": 8}, {"a": 3, "b": 6, "c": 4, "d": 12}]
  }
*/

My current implementation attempts to do something like this:

var skeleton = {
  "a": 0,
  "b": 0,
  "c": 0,
  "d": 0
};

function mergeArrays = function (obj) {
  var flat = {};
  var keys = _.keys(prod);
  var len = obj[keys[0]].length;
  flat["arbitraryname"] = [];
  for (var i = 0; i < len; i++) {
    flat["arbitraryname"].push(skeleton);
  }
  flat["arbitraryname"].forEach(function (v, k) {
    _.forIn(v, function (key, value) {
      flat["arbitraryname"][k][key] += value;
    });
  });
  return flat;
}

Is there any easier way to do that? It also appears to return an array right now that's entirely identical. E.g.:

[{"a": 14, "b": 26, "c": 14, "d": 25}, {"a": 14, "b": 26, "c": 14, "d": 25}, {"a": 14, "b": 26, "c": 14, "d": 25}]

Where each object is a sum of ALL elements in the array. What am I doing wrong? Is there an easier way?

3
  • I think lodash might have something that can do this? Commented Jan 16, 2016 at 5:13
  • what are expected results? That identical set of objects doesn't make sense Commented Jan 16, 2016 at 5:25
  • I didn't clarify this very well. I had an issue where it was pushing the same value for each key in the array. The reason this happened was because assigning the skeleton to the object didn't break the reference to the original object, causing it to update, and cascade down to each key. I fixed this by running JSON.parse(JSON.stringify(skeleton)). I also found a solution that works that's similar, but not exact. I'll try and post it tonight. Commented Jan 18, 2016 at 21:06

2 Answers 2

3

The following matches the commented array at top of question. Expected results are a little unclear

Using Object.keys() makes it fairly easy.

var demo = {
    "key1": [{"a": 4, "b": 3, "c": 2, "d": 1}, {"a": 2, "b": 3, "c": 4, "d": 5}, {"a": 1, "b": 4, "c": 2, "d": 9}],
    "key2": [{"a": 3, "b": 5, "c": 3, "d": 4}, {"a": 2, "b": 9, "c": 1, "d": 3}, {"a": 2, "b": 2, "c": 2, "d": 3}]
};

// iterate and map using first array
var res = demo.key1.map(function(item, idx) { 
    //  loop over keys of each object in array and return 
    //  new objects with sums of matching index and keys
    return Object.keys(item).reduce(function(obj,key) {
        obj[key] = item[key] + demo.key2[idx][key];
        return obj;
    },{});  
});

// print "res" for demo
document.getElementById('pre').innerHTML =JSON.stringify(res, null, 4)
<pre id="pre"></pre>

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

Comments

1

I mean, you could just write it yourself - it's not overly complicated since your rules make it well-defined (plus vanilla is cross-browser compatible):

var resultArray = [];

for(var key in demo) {
  if(demo.hasOwnProperty(key)) {
    demo[key].forEach(function(obj, i) {
      if(!resultArray[i]) {
        resultArray[i] = {};
      }

      for(var letterKey in obj) {
        if(obj.hasOwnProperty(letterKey)) {
          if(resultArray[i][letterKey]) {
            resultArray[i][letterKey] += obj[letterKey];
          } else {
            resultArray[i][letterKey] = obj[letterKey];
          } 
        }
      }
    });
  }
}

That should work.

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.