Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

So I have a multidimensional array like:

myArr = [["venue",2],["venue",16],["inning",2],["inning",4],["inning",32],["hithard", 4]]

I would like to add the similar values up. So in the end I just have:

"venue" = 18, "inning" = 38, and "hithard" = 4.

Can you give me an example of how to accomplish this? Either with Javascript and/or jQuery

Thanks!

share|improve this question
    
Do you want an array or object? Object is { venue=18, inning=36, hithard=4} and Array is [["venue", 18], ["inning", 38], ["hithard", 4]] –  Vega May 7 '12 at 19:52
    
Well I'm going to be turning this into a querystring to pass to a service so I'm sure either will work well –  ksumarine May 7 '12 at 19:54
    
you need a hash (object) –  Gavriel May 7 '12 at 19:55
1  
I'm going to add this to my list of interview questions, it's brought out a ton of interesting approaches –  Mike Robinson May 7 '12 at 20:00
1  
@Corey you can always use $.param to parse the obj to a query string. –  Vega May 7 '12 at 20:11

4 Answers 4

up vote 3 down vote accepted

I am not sure if you want an array or object. If object, stop it is 1st pass and tmp in below code should return you the object as Object { venue=18, inning=38, hithard=4}.

DEMO

var tmp = {}, keys;
for (var i = 0; i < myArr.length; i++) {
    keys = myArr[i][0];
    tmp[keys] = (tmp.hasOwnProperty(keys))? 
              (tmp[keys] + myArr[i][1]):myArr[i][1];
} //tmp - will return you a Object { venue=18, inning=38, hithard=4}

var output = [];
for (keys in tmp) {
    output.push([keys, tmp[keys]]);
} //output will return you an array as [["venue", 18],["inning", 38],["hithard", 4]]     
share|improve this answer
    
this doesn't have query string output, mine below does –  Gavriel May 7 '12 at 20:00
    
@Downvoter please leave a comment –  Vega May 7 '12 at 20:02
    
@Gavriel OP mentions that he will be using it in query string. However initial post doesn't say anything about query string. Let say if he want this in AJAX data, then he can just use it right away.. –  Vega May 7 '12 at 20:03
    
@Gavriel that's a pretty good solution also, thank you –  ksumarine May 7 '12 at 20:04
    
+1 for a good solution. Downvoter, you are not right. –  VisioN May 7 '12 at 20:20
myArr = [["venue",2],["venue",16],["inning",2],["inning",4],["inning",32],["hithard", 4]];
values = {};
for (i=0;i<myArr.length;i++){
   if ("undefined" == typeof values[myArr[i][0]]) {values[myArr[i][0]] = 0;}
   values[myArr[i][0]] += myArr[i][1];
}
arr = [];
query_string = "";
for (i in values) {
    // if you want it in an array:
    arr.push('"' + i + '" = ' + values[i]);
    query_string += (query_string.length ? "&" : "") + i + "=" + values[i];
}
​console.log(arr);​

DEMO: http://jsfiddle.net/Ta97E/2/

you can use values to create the query string

share|improve this answer
    
you're right, here's a fixed version! –  Gavriel May 7 '12 at 19:37
    
what's wrong with it? This is dynamic and it sums them by category –  Gavriel May 7 '12 at 19:44
1  
I see what you are going for here Gavriel. This solution goes toward the idea of not limiting your code to a static requirement. What if a fourth or fifth statistic was needed? by creating the object based on the key and then incrementing into that key value pair, this solves the problem. I would have approached it only slightly different. This does not deserve a down vote. –  C.S. May 7 '12 at 19:45
    
@MikeRobinson Where in the question does he specify that the answer has to be an array result? That is a terrible assumption. The question effectively asks, "how do I add these three things up". –  C.S. May 7 '12 at 19:49
    
@ChristopherSmithson You have a point, I was just going with the idea of maintaining datatypes just in case there's part of the code further on that rely on this configuration. –  Mike Robinson May 7 '12 at 19:51

Underscore solution:

 sums = _.reduce(myArr, function (obj, item) { 
    obj[item[0]] = (obj[item[0]] || 0) + item[1]; 
    return obj; 
 }, {});

 // sums = {"venue":18,"inning":38,"hithard":4}

A little dirtier in jQuery

sums = {}

$.each(myArr, function (i, value) {
    sums[value[0]] = (sums[value[0]] || 0) + value[1];
});

Edit: add jQuery version

share|improve this answer
    
I like your dirty jQuery solution also. Thank you! –  ksumarine May 7 '12 at 20:04

Check this code:

var final = {};
for (var i in myArr) {
    var item = myArr[i];
    final[item[0]] = (final[item[0]] || 0) + item[1];
}

console.log(final);​

DEMO: http://jsfiddle.net/UVJEb/

share|improve this answer
    
strictly speaking it misses if (myArr.hasOwnProperty(i)), otherwise it would be a perfect general solution –  Otto Allmendinger May 7 '12 at 20:00
    
@OttoAllmendinger You mean final.hasOwnProperty? I think (final[item[0]] || 0) covers it absolutely. Can't imagine the situation when it won't work. –  VisioN May 7 '12 at 20:05
    
the hasOwnProperty check filters inherited properties: stackoverflow.com/a/86306/92493 –  Otto Allmendinger May 7 '12 at 20:16

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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