1

I have following JavaScript objects (new_object and old_object):

new_object:

0300 : ["295", "293", "298"],
0800 : ["293", "298"],
0930 : ["295"],
1130 : ["297", "293", "298"],
1230 : ["295"]

old_object:

0300 : ["297"],
0800 : ["297"],
0930 : ["293"],

I want to merge them so that final object would be like

0300 : ["295", "293", "298", "297"],
0800 : ["293", "298", "297"],
0930 : ["295", "298", "293"],
1130 : ["297", "293", "298"],
1230 : ["295", "298"]

I tried new_object['0300'].push with each loop but its not working

How could I merge JavaScript objects ? Are there any best practices?

Vikram
  • 3,171
  • 7
  • 37
  • 67
  • Could you include the code you have tried with? Could you explain what exactly is not working, maybe giving us the output you currently get? – trincot Oct 25 '15 at 07:52
  • I don't understand the logic. Why would the `0930` key in the result contain `298`? Also, be careful with your keys: if you mean them as strings, fine, but `0300` is an octal constant which means `192`. –  Oct 25 '15 at 07:53
  • yes the keys are strings – Vikram Oct 25 '15 at 08:50

5 Answers5

1

try this :

for (var key in new_object){
    if(old_object.hasOwnProperty(key)){
        new_object[key] = new_object[key].concat(old_object[key]);
    } 
}
  • Won't this concat `undefined` if the key is missing in `old_object`? –  Oct 25 '15 at 07:54
  • @torazaburo if there are some missing key in it , insert an if condition before concat to check the validity of old_object[key] – MohammadJavad Seyyedi Oct 25 '15 at 07:56
  • 1
    What if `old_object` has properties that are not in `new_object`? –  Oct 25 '15 at 08:01
  • @torazaburo object's key are known as properties of object. by checking this condition you are checking if the key of old_object is valid or not – MohammadJavad Seyyedi Oct 25 '15 at 08:03
  • @torazaburo i updated the answer to consider the case you mentioned that is "if old_object has properties that are not in new_object – Vikram Oct 25 '15 at 09:35
  • The only problem i am facing is it now have similar items in new object after cancat. is there any way to do it easily and without using loop ? – Vikram Oct 25 '15 at 09:39
  • instead of new_object[key] = new_object[key].concat(old_object[key]); use: for (var i = 0; i < old_object[key].length; i++) { if (new_object[key].indexOf(old_object[key][i]) > -1) {new_object[key].push(old_object[key][i]); } } – Majid Yaghouti Oct 25 '15 at 09:57
  • @Sherif you made a mistake in my answer after edit. the if condition nchecks the validity of old_object[key] and if it's not true means there is not any thing in old_object[key] and it's a mistake to new_object[key] = old_object[key]; – MohammadJavad Seyyedi Oct 25 '15 at 10:47
  • @MohammadJavadSeyyedi My apologies. Please feel free to edit it back. – Sherif Oct 25 '15 at 10:48
  • This accepted answer does not produce the desired results as stated in the question, whether or not that is due to a mistake by the OP in showing his desired results I cannot say. For instance, for 0930, it results in ` ["295", "293"]` instead of `["295", "298", "293"]` –  Oct 25 '15 at 11:38
0

You can also use jquery $.merge()

var result = $.merge(oldArray, newArray);

check this

Community
  • 1
  • 1
Vinodhan
  • 110
  • 4
  • Did you test this? I don't think it will do what you want. Also, in general, unless the OP tagged his question jQuery a non-jQuery answer is preferred. –  Oct 25 '15 at 07:57
  • yes @torazaburo I have tested this, please check working jsfiddle http://jsfiddle.net/vinodhan/hootuoph/ – Vinodhan Oct 25 '15 at 08:01
  • Your fiddle merges individual property values. The job is to merge **each** pair of properties. See http://jsfiddle.net/hootuoph/1/. –  Oct 25 '15 at 08:03
0

I think new_object['0300'].push is a wrong syntax. Try to new_object[0300].push. It works. But output is something strange.

var newObject = {0300 : ["295", "293", "298"],0800 : ["293", "298"],0930 : ["295"],1130 : ["297", "293", "298"],1230 : ["295"]}
var oldObject = {0300 : ["297"],0800 : ["297"],0930 : ["293"]}
newObject[0300].push(oldObject[0300])
//console outputs: ["295", "293", "298", ["297"]] 

So I use concat method.

var newObject = {0300 : ["295", "293", "298"],0800 : ["293", "298"],0930 : ["295"],1130 : ["297", "293", "298"],1230 : ["295"]}
var oldObject = {0300 : ["297"],0800 : ["297"],0930 : ["293"]}

newObject[0300].concat(oldObject[0300])
//console outputs: ["295", "293", "298", "297"]

Finally, Merge two Json objects. Try this.

And see this Questions > How can I merge properties of two JavaScript objects dynamically?

for (var attrname in obj2) { obj1[attrname] = obj2[attrname]; }
Community
  • 1
  • 1
Minwoo
  • 213
  • 4
  • 12
0

Actually made a proper solution...

var final_object = {};

var new_object_properties = Object.getOwnPropertyNames(new_object);
var old_object_properties = Object.getOwnPropertyNames(old_object);
var new_object_properties_length = new_object_properties.length;
var old_object_properties_length = old_object_properties.length;
if(new_object_properties_length >  old_object_properties_length)
while(--new_object_properties_length){
     var property_name = new_object_properties[new_object_properties_length];
     if(old_object[property_name])
          final_object[property_name] = new_object[property_name].concat(old_object[property_name];
     else
         final_object[property_name] = new_object_properties[new_object_properties_length];
}
else
    while(--old_object_properties_length){
     var property_name = old_object_properties[old_object_properties_length];
     if(new_object[property_name])
          final_object[property_name] = old_object[property_name].concat(new_object[property_name];
     else
         final_object[property_name] = old_object_properties[old_object_properties_length];
}
Olavi Sau
  • 1,647
  • 13
  • 20
  • This algorithm has the rather unfortunate characteristic that for keys in both old and new objects, it will concatenate once in the first loop, then throw that result away and concatenate again in the second loop. –  Oct 25 '15 at 11:40
  • Yeah, I am confident that there is a better way, just the one I came up with quickly. EDIT: Oh i see its an easy fix :D – Olavi Sau Oct 25 '15 at 20:52
0

First, write a utility function to merge properties with the same key in two objects, based on a merge strategy passed in as a function.

To merge properties with the same key in two objects, we loop over the second list of keys, and either merge the value into the first object (if it has a property with same key), or simply copy it over (if it doesn't). The way this is written it will mutate (overwrite) o1:

function merge_keys(o1, o2, merge) {
  var keys2 = Object.keys(o2), key;

  for (var i = 0; i < keys2.length; i++) {
    key = keys2[i];
    o1[key] = o1[key] ? merge(o1[key], o2[key]) : o2[key];
  }
}

Define the merging strategy you want to use:

function concat(a, b) { return a.concat(b); }

Then

merge_keys(new_object, old_object, concat);

See http://jsfiddle.net/hootuoph/2/.

If you are programming in ES6, you can write this more compactly using for...of:

function merge_keys(o1, o2, merge) {
  for (var k of Object.keys(o2)) {
    o1[k] = o1[k] ? merge(o1[k], o2[k]) : o2[k];
  }
}

Or if you prefer using Array#forEach:

function merge_keys(o1, o2, merge) {
  function maybe_merge(k) { o1[k] = o1[k] ? merge(o1[k], o2[k]) : o2[k]; }

  Object.keys(o2).forEach(maybe_merge);
}