views:

385

answers:

5

I am looking for the best way to augment multiple javascript associative arrays.

For example the following code

a = { "one" : 1, "two" : 2 };
b = { "three" : 3 };
c = { "four" : 4, "five" : 5 };

d = Collect(a,b,c)

Should result in value of d being:

{ "one" : 1, "two" : 2, "three" : 3, "four" : 4, "five" : 5   };

What is the best way to do this?

+2  A: 
function Collect(a, b, c) {
    for (property in b)
        a[property] = b[property];

    for (property in c)
        a[property] = c[property];

    return a;
}

Notice: Existing properties in previous objects will be overwritten.

Björn
This has the side-effect that `a === d` at the end. That might be ok and it might not.
tvanfosson
+6  A: 

This should do it:

function collect() {
  var ret = {};
  var len = arguments.length;
  for (var i=0; i<len; i++) {
    for (p in arguments[i]) {
      if (arguments[i].hasOwnProperty(p)) {
        ret[p] = arguments[i][p];
      }
    }
  }
  return ret;
}

Input:

a = { "one" : 1, "two" : 2 };
b = { "three" : 3 };
c = { "four" : 4, "five" : 5 };
d = collect(a, b, c);
console.log(d);

Output:

Object one=1 two=2  three=3 four=4 five=5
cletus
Doesn't `length` lookup the size of the array at each invocation? I'm so used to writing `for (var i = 0, len = array.length; i < len; ++i)` that I can't remember off the top of my head why I started doing it.
tvanfosson
Yes, that's correct. It is better performance to cache the length once. However, because the size of the arguments "array" is not likely to ever be very large, it won't really matter in this case.
jhurshman
No, except slightly on IE6. Accessing the length property costs the same as accessing the len variable.
Alsciende
@Alsciende, I believe that is incorrect. For large arrays, you should always cache length when iterating. @cletus Why are you using hasOwnProperty, prototype user?
Juan Mendes
@Juan I believe you are incorrect, and I did some tests to make up my mind. Caching the length is an easy myth of optimization that's been obsolete for many years, and it makes the code (slightly) less readable. Actually, caching the length sometimes slows down the browser (Safari).
Alsciende
@Alsciende It is true that I hadn't run any length caching tests in a while, and in doing so, I did find that caching the length is not significantly faster for newer browsers, webkit, firefox and IE8. However, I code for the corporate world that is infested with IE6. So I'll keep caching my length.
Juan Mendes
+4  A: 

jQuery has a nice way of doing this.

http://api.jquery.com/jQuery.extend/

dpb
+1 Even if you don't use jQuery's method, you could use their code to help construct your own (perhaps, more specific) implementation.
tvanfosson
And if you aren't using jQuery, you *should* be. :)
Randal Schwartz
@Randal: There are many perfectly good reasons for not using jQuery.
Tim Down
+1  A: 
function collect(a, b, c){
    var d = {};

    for(p in a){
        d[p] = a[p];
    }
    for(p in b){
        d[p] = b[p];
    }
    for(p in c){
        d[p] = c[p];
    }

    return d;
}
Álvaro G. Vicario
+1  A: 

Why should the function be restricted to 3 arguments? Also, check for hasOwnProperty.

function Collect() {
    var o={};
    for(var i=0;i<arguments.length;i++) {
      var arg=arguments[i];
      if(typeof arg != "object") continue;
      for(var p in arg) {
        if(arg.hasOwnProperty(p)) o[p] = arg[p];
      }
    }
    return o;
}
Alsciende