1

I have two arrays that I need to merge together, they look like so:

var array1 = 
[
  {x: "1/12/2011", y: 4149.9}
  {x: "2/12/2011", y: 4094.5}
  {x: "3/12/2011", y: 3606.8}
]

and

var array2 =
[
  {x: "1/12/2011", z: 3500}
  {x: "2/12/2011", z: 3600}
  {x: "3/12/2011", z: 3700}
]

I would like to merge them based on x where all properties are kept in the final object.

Expected output:

var excpected =
[
  {x: "1/12/2011", y: 4149.9, z: 3500}
  {x: "2/12/2011", y: 4094.5, z: 3600}
  {x: "3/12/2011", y: 3606.8, z: 3700}
]

I've found $.extend and $.merge but haven't managed to successfully achieve what I need. Any pointers?

m.edmondson
  • 30,382
  • 27
  • 123
  • 206
  • 1
    Those are not valid arrays... – Soolie Dec 08 '17 at 11:13
  • *"I would like to merge them"* Okay. Where are you stuck? What has your research turned up? Or your extensive searching here on SO? – T.J. Crowder Dec 08 '17 at 11:15
  • does the arrays have the same grouping value at the same index? – Nina Scholz Dec 08 '17 at 11:16
  • @T.J.Crowder - See where you're coming from, mainly had my head in the jQuery docs and console tying to figure it out. Research just found those two jQuery methods but I seemed to be unable to manipulate them how I want. Therefore hit a wall and needed some insight from SO. – m.edmondson Dec 08 '17 at 11:18
  • Cool, linked dupetarget should show you how, particularly [Oriol's answer](https://stackoverflow.com/a/30335130/157247). FYI, `$.extend` is one of the many library utility methods that led to `Object.assign` being added to JS. (You could use `$.extend` instead of `Object.assign` if you wanted in his code, for instance, although `Object.assign` is trivial to polyfill.) – T.J. Crowder Dec 08 '17 at 11:20

4 Answers4

1

Use Object.assign and array.prototype.map:

var array1 = 
[
  {x: "1/12/2011", y: 4149.9},
  {x: "2/12/2011", y: 4094.5},
  {x: "3/12/2011", y: 3606.8}
];

var array2 =
[
  {x: "1/12/2011", z: 3500},
  {x: "2/12/2011", z: 3600},
  {x: "3/12/2011", z: 3700}
]

var merged = array1.map((e, index) => Object.assign({}, e, array2.find(a => a.x === e.x)));

console.log(merged);
Faly
  • 13,291
  • 2
  • 19
  • 37
1

Just use map method in combination with Object.assign

var array1 = 
[
  {x: "1/12/2011", y: 4149.9},
  {x: "2/12/2011", y: 4094.5},
  {x: "3/12/2011", y: 3606.8}
]
var array2 =
[
  {x: "1/12/2011", z: 3500},
  {x: "2/12/2011", z: 3600},
  {x: "3/12/2011", z: 3700}
]
var expected = array1.map( (a,i) => Object.assign(a, array2.find(b=>b.x == a.x)));
console.log(expected);
Mihai Alexandru-Ionut
  • 47,092
  • 13
  • 101
  • 128
  • Although in the example data he has used both arrays are in the same order etc, there is this little bit `I would like to merge them based on x`. You might want to add a find in there. – Keith Dec 08 '17 at 11:16
1

While rest of answers are almost correct, but they miss the point of matching x

var array1 = [{
  x: "1/12/2011",
  y: 4149.9
}, {
  x: "2/12/2011",
  y: 4094.5
}, {
  x: "3/12/2011",
  y: 3606.8
}]

var array2 = [{
  x: "1/12/2011",
  z: 3500
}, {
  x: "2/12/2011",
  z: 3600
}, {
  x: "3/12/2011",
  z: 3700
}]

var excpected = array1.map(item => {
  var fromArray2 = array2.filter(array2Item => array2Item.x === item.x)[0];
  item.z = fromArray2.z;
  return item;
})

console.log(excpected);
Vipin Kumar
  • 6,441
  • 1
  • 19
  • 25
0

You can array#concat your array and then use array#reduce to merge them based on value of x.

var array1 = [ {x: "1/12/2011", y: 4149.9}, {x: "2/12/2011", y: 4094.5}, {x: "3/12/2011", y: 3606.8} ],
    array2 = [ {x: "1/12/2011", z: 3500}, {x: "2/12/2011", z: 3600}, {x: "3/12/2011", z: 3700} ];

var result = array1
              .concat(array2)
              .reduce((r, o) => {
                r[o.x] = Object.assign({},r[o.x] || {}, o);
                return r;
              },{});
var output = Object.values(result);
console.log(output);
Hassan Imam
  • 21,956
  • 5
  • 41
  • 51