2

I am looking for a javascript function like PHP array_merge_recursive(). From what I've read, there is no such thing in javascript, and I want to know how I can implement something similar.

The problem:

I have two objects:

 var obj1 = {
  "AUDCAD": {
    "t": [1439238600, 1439238600],
    "o": [0.9646, 0.9646],
    "h": [0.9646, 0.9646],
    "l": [0.9645, 0.9645],
    "c": [0.9645, 0.9645],
    "v": [15, 15]
  },
  "AUDCHF": {
    "t": [1439238600, 1439238600],
    "o": [0.7291, 0.7291],
    "h": [0.7292, 0.7292],
    "l": [0.729, 0.729],
    "c": [0.7291, 0.7291],
    "v": [6, 6]
  }
};

var obj2 = {
  "AUDCAD": {
    "t": [111],
    "o": [111],
    "h": [111],
    "l": [111],
    "c": [111],
    "v": [111]
  },
  "AUDCHF": {
    "t": [111],
    "o": [111],
    "h": [111],
    "l": [111],
    "c": [111],
    "v": [111]
  }
};

Of those objects I need to create a new one like this:

   var obj3 =  {
      "AUDCAD": {
        "t": [1439238600, 1439238600, 111], //Note that the value "111" is added from obj2 to the end of obj1.
        "o": [0.9646, 0.9646, 111],
        "h": [0.9646, 0.9646, 111],
        "l": [0.9645, 0.9645, 111],
        "c": [0.9645, 0.9645, 111],
        "v": [15, 15, 111]
      },
      "AUDCHF": {
        "t": [1439238600, 1439238600, 111],
        "o": [0.7291, 0.7291, 111],
        "h": [0.7292, 0.7292, 111],
        "l": [0.729, 0.729, 111],
        "c": [0.7291, 0.7291, 111],
        "v": [6, 6, 111]
      }
    }

What im doing:

/* 
Code seen here: 
http://stackoverflow.com/questions/171251/how-can-i-merge-properties-of-two-javascript-objects-dynamically
Author: Scdev
*/

function extendObjects() {

  var newObject = {};
  var overwriteValues = false;
  var overwriteObjects = false;

  for (var indexArgument = 0; indexArgument < arguments.length; indexArgument++) {

    if (typeof arguments[indexArgument] !== 'object') {

      if (arguments[indexArgument] == 'overwriteValues_True') {

        overwriteValues = true;
      } else if (arguments[indexArgument] == 'overwriteValues_False') {

        overwriteValues = false;
      } else if (arguments[indexArgument] == 'overwriteObjects_True') {

        overwriteObjects = true;
      } else if (arguments[indexArgument] == 'overwriteObjects_False') {

        overwriteObjects = false;
      }

    } else {

      extendObject(arguments[indexArgument], newObject, overwriteValues, overwriteObjects);
    }

  }

  function extendObject(object, extendedObject, overwriteValues, overwriteObjects) {

    for (var indexObject in object) {

      if (typeof object[indexObject] === 'object') {

        if (typeof extendedObject[indexObject] === "undefined" || overwriteObjects) {
          extendedObject[indexObject] = object[indexObject];
        }

        extendObject(object[indexObject], extendedObject[indexObject], overwriteValues, overwriteObjects);

      } else {

        if (typeof extendedObject[indexObject] === "undefined" || overwriteValues) {
          extendedObject[indexObject] = object[indexObject];
        }

      }

    }

    return extendedObject;

  }

  return newObject;
}


var newExtendedObject = extendObjects('overwriteValues_False', 'overwriteObjects_False', obj1, obj2);

I am using nodejs and I have tried without success with some libraries, I've also read some similar questions here but not found a solution to my problem. Any suggestions on how I can solve? Thanks everyone for your time.

Temporal solution

Temporarily solved my problem with array.push()

//Pseudo-code    
obj1[0]["AUDCAD"]["t"].push(obj2[0]["AUDCAD"]["t"]);
Max
  • 168
  • 1
  • 7
  • I recomend to you lodash https://lodash.com/docs#merge – Raúl Martín Aug 11 '15 at 19:27
  • Could you define the desired behavior a bit better? What types should be merged, overwritten, added to a list, etc.? – pzp Aug 11 '15 at 19:51
  • @pzp In simple words, I need to append `values` of `obj2` at end of `obj1` keeping `keys` and `values` of both, so the result should look like the `obj3` sample code. – Max Aug 11 '15 at 20:06

2 Answers2

0

This function assumes that all the keys and sub-keys in object x are in object y and vice versa.

function merge(x, y) {
    var result = {};
    Object.keys(x).forEach(
        function (k) {
            result[k] = {};
            Object.keys(x[k]).forEach(
                function (j) {
                    if (j in y[k]) {
                        result[k][j] = x[k][j].concat(y[k][j]);
                    }
                });
        });
    return result;    
}

Test run:

merge(obj1, obj2);
=> { AUDCAD: 
   { t: [ 1439238600, 1439238600, 111 ],
     o: [ 0.9646, 0.9646, 111 ],
     h: [ 0.9646, 0.9646, 111 ],
     l: [ 0.9645, 0.9645, 111 ],
     c: [ 0.9645, 0.9645, 111 ],
     v: [ 15, 15, 111 ] },
  AUDCHF: 
   { t: [ 1439238600, 1439238600, 111 ],
     o: [ 0.7291, 0.7291, 111 ],
     h: [ 0.7292, 0.7292, 111 ],
     l: [ 0.729, 0.729, 111 ],
     c: [ 0.7291, 0.7291, 111 ],
     v: [ 6, 6, 111 ] } }
Adeel Zafar Soomro
  • 1,492
  • 9
  • 15
-1
Object.prototype.merge = function(obj) {

    if (typeof this !== 'object' 
       || obj === undefined 
       || typeof obj !== 'object')
        return;

    var self = this,
       arr = {},
       i;

    for (i in self) {
        if (typeof obj[i] !== 'undefined'
         && typeof self[i] === typeof obj[i]) {
            self[i].merge(obj[i]);
            arr[i] = true;
         }
    }

    for (i in obj) {
        if (!arr[i])
           self[i] = obj[i];
    }
};

Array.prototype.merge = function(obj) {
    if (typeof obj !== 'undefined'
        && !(obj instanceof Array))
        return;

    var self = this,
       i;
    for (i = 0; i < obj.length; i++)
       self.push(obj[i]);
};

To run

obj1.merge(obj2);

The data will be appended to obj1

Vicky
  • 3,230
  • 3
  • 18
  • 21
  • 1
    Extending the Object prototype is not the way to go imo. Everything from Arrays to Strings to Booleans will have that method available to them. – elad.chen Aug 11 '15 at 21:14
  • 1
    My point here was you can do something like this. You can define your specific objects and have merge method in them. For objects which do not have merge will simply ignore. – Vicky Aug 11 '15 at 23:45