1

Sorry if the title isn't that clear. This is kind of hard to explain for me, as I'm not that good when it comes to multiple arrays.

I have an array: [ [21, 1000], [21, 500], [18, 100], [18, 200] ]

Now I want to get this resulting array: [ [21, 1500], [18, 300] ]

How do I go about doing this?

I've tried using 21 and 18 as array keys, but this way I couldn't use the array in a for loop with .length counting. I ended up with a total of 4 arrays to almost get it working.


Edit:

I want to avoid using the 21 and 18 values as array keys.

I also want to be able to iterate over the resulting array/object, and use the 21 and 18 "keys" as well, to make some further changes to my page.

Thanks already for all the responses!

4
  • You cannot use for but you can actually use .each() for object. Commented May 9, 2013 at 18:03
  • Why not store the data as objects in the second array? Commented May 9, 2013 at 18:05
  • It isn't clear what should happen in a case where an element from "first" is not found in "second", or in a case where there is a pair in "second" but there is no matching element in "first". This could make a number of the answers already given, incorrect. Commented May 9, 2013 at 18:45
  • The first array seemed to be redundant, so no need to check against another array anymore. Post updated. Commented May 9, 2013 at 19:09

5 Answers 5

6

How about creating an object :

var arr = [ [21, 1000], [21, 500], [18, 100], [18, 200] ];
    obj = {};

for (i=0; i<arr.length; i++) {
    obj[arr[i][0]] = (obj[arr[i][0]] || 0) + arr[i][1];
}

// obj now equals {18: 300, 21: 1500} 
// obj[21] equals 1500 etc

FIDDLE

You could create an array the same way :

var arr  = [ [21, 1000], [21, 500], [18, 100], [18, 200] ],
    arr2 = [];

for (i=0; i<arr.length; i++) {
    arr2[arr[i][0]] = (arr2[arr[i][0]] || 0) + arr[i][1];
}

// giving you the array [18: 300, 21: 1500]
// where arr2[18] equals 300
Sign up to request clarification or add additional context in comments.

13 Comments

@ryan - Not sure I get it, why would'nt that work -> Fiddle ? The order in the array does'nt matter!
Sorry, I got mixed up cause I was writing something else. The order of the second array doesn't matter, however, he has 2 arrays and he is checking the values in the first against the values in the second. You completely ignore the first array. What I meant by the if statement was: what if he has the above array but his first array looks like this [53, 18]? It was a lack of dealing with the first array I was getting after.
@ryan - that was the point of the object. Arrays don't have keys, they only have indices, so creating an object from the values in the second array, it would be trivial to see if the values in the first array are in fact keys in the object, as objects actually have keys.
@adeneo Could you please explain what the || operator does in order to achieve the sum?
@jlmmns - You'd do that with a for / in loop, like this FIDDLE
|
2

You definitely don't need any jQuery for this to get the result array you asked for:

var one = [21, 18];
var two = [ [21, 1000], [21, 500], [18, 100], [18, 200] ];
var results = [];

for(var i in one) {
    results[i] = 0;

    for(var x in two)
        if(two[x][0] === one[i])
            results[i] = results[i] + two[x][1];

    results[i] = [one[i], results[i]];
}

Fiddle here

1 Comment

I went with this solution, as it allows me to iterate over the results and use the 21/18 "keys" in my output as well.
0

in case your values are not in order, you can use this:

fiddle:
http://jsfiddle.net/acturbo/YWaja/

javasript:

var array1=    [21, 18];
var array2 =   [ [21, 1000], [21, 500], [18, 100], [18, 200] ];
var result =   [ [0,0], [0,0] ];

for (i=0;i<array1.length;i++){

    result[0,i][0] = array1[i];

    for (j=0;j<array2.length;j++){

        var key = array2[i,j][0];
        var val = array2[i,j][1];

        if (  key == array1[i] ){
            result[0,i][1] += val;
        }
    }
}

Comments

0
function aggregateResults(indexes, inputArray) {
  var ret = [], tmp;
  for (var i=0; i<indexes.length; i++) {
    tmp = 0;
    for (var j=0; j<inputArray.length; j++) {
      tmp += inputArray[j][0] == indexes[i] ? inputArray[j][1] : 0;
    }
    ret.push([indexes[i], tmp])
  }
  return ret;
}

Comments

0

Here is another possibility, it is using Array.forEach, so you need to have a modern browser or use one of the many "shims"/"polyfills" out there.

Javascript

var first = [21, 18],
    second = [
        [21, 1000],
        [21, 500],
        [18, 100],
        [18, 200]
    ],
    store = {};
    result = [];


first.forEach(function (element) {
    second.forEach(function (pair) {
        var value;

        if (pair[0] === element) {
            value = store[element] || 0;
            store[element] = value + pair[1];
        }
    });

    if (typeof store[element] === "number") {
        result.push([element, store[element]]);
    }
});

console.log(result);

On jsfiddle

Update: here is a solution based on the updated question, this also uses Object.keys and Array.map to do the conversion from an object to the array format that the OP has requested.

Javascript

var first = [
        [21, 1000],
        [21, 500],
        [18, 100],
        [18, 200]
    ],
    store = {};
    result;

first.forEach(function (pair) {
    store[pair[0]] = (store[pair[0]] || 0) + pair[1];
});

result = Object.keys(store).map(function (key) {
    return [parseInt(key, 10), store[key]];
});

console.log(result);

On jsfiddle

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.