2
\$\begingroup\$

I would like to be able to use it with IE8 or earlier, so I'm staying away from newer array methods. I'm not an expert so my code may not be the most efficient choice, but it works.

var data = [
["John", 2],
["Jenny", 3],
["John", 4],
["Beavis", 5]]

var newarr = [["John",5]];

for (var x=0; x < data.length; x++) {   

    for (var y=0; y < newarr.length+1; y++) {           
        if (typeof newarr[y] !== 'undefined') {         
            if (newarr[y][0] == data[x][0]) {               
                newarr[y][1] = (newarr[y][1] + data[x][1]);
                break;
            }           
        }
        else {
            newarr.push([data[x][0]]);
            newarr[y][1] = data[x][1];
            break;
        }   
    }

}

alert("newarr is: " + newarr);

//if elements are similar, merge them.

Would like to find out if this is a decent way of doing it, or maybe there are other easier/less code ways of doing it. Maybe somebody sees an issue with this code that I do not. Thanks.

\$\endgroup\$
3
  • 1
    \$\begingroup\$ About your "stay away from newer array methods", have you considered ES5-Shim? \$\endgroup\$ Commented Mar 12, 2012 at 19:13
  • 1
    \$\begingroup\$ You should not do data.length in the for loop for the end condition, declare length as a local variable and use that in the for loop. \$\endgroup\$ Commented Mar 12, 2012 at 23:44
  • 1
    \$\begingroup\$ @epascarello This impairs readability and conciseness. The improvement is probably non significant. \$\endgroup\$ Commented Mar 13, 2012 at 14:58

2 Answers 2

4
\$\begingroup\$

You should take a look at the Underscore javascript library, which contains a number of methods for comparing and manipulating arrays and objects.

I'm using the _.intersection and _.keys methods to compare your two objects. I've also taken the liberty of restructuring your arrays into objects, which I think makes more sense for what you're trying to do.

// Adds the values of keys that are the same between any two objects    
function addObjects(a, b) {
  var sameKeys = _.intersection(_.keys(a), _.keys(b)),      // Creates array of similary keys. eg ["John", "Jenny", "Amanda"]
      sumObj = {}

  // Loop through sameKeys, and add values from both objects
  for(i=0; i < sameKeys.length; i++) {
    var thisKey = sameKeys[i];
    sumObj[thisKey] = a[thisKey] + b[thisKey];              // eg. sumbObj["John"] = a["John"] + b["John"] = 7 
  }

  return sumObj;
}

var firstObj = {
  "John" : 2,
  "Jenny" : 3,
  "Beavis" : 5,
  "Toby": 6,
   "Amanda": 12
}

var secondObj = {
  "John": 5,
  "Jenny": 18,
  "Amanda": 2
}


mySumObj = addObjects(firstObj, secondObj);
/* 
mySumObj = {
    "Amanda": 14,
    "Jenny": 21,
    "John": 7
}
*/

I hope this helps you. It may help if you could explain a bit more what your end goal here is.

\$\endgroup\$
0
2
\$\begingroup\$

Some general advice:

  • You should use a function, even in this demonstration code. It's makes it clearer what the input and output are.
  • You should chose better variable names. newarr doesn't make sense, since it's not "new" but pre-filled. And x and y should have names that reflect that they are the indexes of data and newarr respectively.
  • It seems that the inner structure (["John", 5]) could be better represented as an object ({name: "John", value: 5} or even {"John": 5}).
  • It depends on what you are doing with your result, but it may be sensible not to modify newarr, but create a separate result array.

Actually I just realize you are modifing newarr while iterating over it. That is something you never should do, since it's a potential for bugs. I haven't checked, but I'm quite sure that the code won't work the way you expect it to like that.

\$\endgroup\$
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.