2

I have the following js array:

for(var j = 0; j < array.length; j++){
  arr.push([array[j][0],array[j][1],array[j][2]]);
}

And it translates into this:

Number, type, qty

[[12345, "product", "10"],[12345, "product", "15"],[1234567, "other", "10"]]

What I've been trying to do is to filter the unique product number array[j][0] and sum the qty array[j][2] if there's more than one and I was able to do the unique filter by doing the following:

for(var o = 0; o < arr.length; o++){
  if (!n[arr[o][1]]){
     n[arr[o][1]] = true
     r.push(arr[o]);
  }
}

I would like your help to figure this out.. What I'm expecting to achieve is something like this:

[[12345, "product", "25"],[1234567, "other", "10"]]

Since product 12345 was repeated I only need to display it once and sum the qty of the other products with the same product number.

11
  • So you want a hash of product IDs and their running totals? Commented Mar 10, 2016 at 22:30
  • Yes, filtering out the unique numbers and adding up the totals @DaveNewton Commented Mar 10, 2016 at 22:40
  • 1
    (That was hint: use the hash to track IDs, when you iterate over an item with an existing array, do math; when you find an ID w/o a value, create the new entry with the price.) Commented Mar 10, 2016 at 22:43
  • Have you considered moving this piece of business logic to the back end? In a production system, it's going to be much easier and more efficient to write queries to achieve what you want. Commented Mar 10, 2016 at 22:43
  • @NicholasByfleet My guess is that this is an assignment, so it would not matter. Commented Mar 10, 2016 at 22:44

5 Answers 5

3
var productIndex = {};
var result = [];
for (var i = 0; i < arr.length; i++) {
  var productId = arr[i][0];
  if (productIndex[productId] === undefined) {
    productIndex[productId] = result.length;
    result.push(arr[i]);
  } else {
    var index = productIndex[productId];
    result[index][2] = String(+result[index][2] + +arr[i][2]);
  }
}
Sign up to request clarification or add additional context in comments.

3 Comments

I can see where you are going with this, it makes sense. I haven't been able to make it work though
What are you having trouble with? It works for your sample array.
My mistake was replacing === with == This works!! Thanks
0

I am sure there are better ways. But I just changed it to an object, added them and changed it back to an array. Here you go:

https://jsfiddle.net/ct6to1Lv/

var a = [[12345, "product", "10"],[12345, "product", "15"],[1234567, "other", "10"]];
var b = {};
var c = [];

for(var i = 0; i < a.length; i++) {
    if(!b.hasOwnProperty(a[i][0])) {
    b[a[i][0]] = {};
    b[a[i][0]]['qty'] = 0;
  }
  b[a[i][0]]['id'] = a[i][0];
  b[a[i][0]]['name'] = a[i][1];
    b[a[i][0]]['qty'] += parseInt(a[i][2]);
}

for(key in b) {
    c[c.length] = [b[key]['id'], b[key]['name'], b[key]['qty']];
}

$(function(){
$('#console').append(a.toString()+'<br />');
$('#console').append(JSON.stringify(b)+'<br />');
$('#console').append(c.toString());
});

Comments

0
var arr = [[12345, "product", "10"],[12345, "product", "15"],[1234567, "other", "10"]];

var obj = {};

arr.forEach(function(e){
    var t = e[0];
    if(obj[t]) {
        obj[t][2] += +e[2];
    } else {
        t = [];
        t[0] = e[0];
        t[1] = e[1];
        t[2] = +e[2];
        obj[e[0]] = t;
    }
});

var res = [];

Object.keys(obj).forEach(function(k) {
    res.push(obj[k]);
});

console.log(res);

Result:

[ [ 12345, 'product', 25 ], [ 1234567, 'other', 10 ] ]

Comments

0

To complete the possibillities, here a solution with a temporary object, which is hidden in this.

var data = [[12345, "product", "10"], [12345, "product", "15"], [1234567, "other", "10"]],
    result = function (data) {
        var r = [];
        data.forEach(function (a) {
            if (!this[a[0]]) {
                this[a[0]] = [a[0], a[1], 0];
                r.push(this[a[0]]);
            }
            this[a[0]][2] += +a[2];
        }, {});
        return r;
    }(data);

document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');

Comments

0

The reduce() method applies a function against an accumulator and each value of the array (from left-to-right) to reduce it to a single value.

See Array.prototype.reduce() and Array.prototype.sort()

var list = [[12345, "product", "10"], [12345, "product", "15"], [1234567, "other", "10"], [12345, "product", "5"]];

//first we sort the array by id
//@pv = previous value; @cv = current value
list.sort(function(pv, cv) {
    var a = +pv[0],
        b = +cv[0];
    return a - b;
});

//reduce the array for repeated elements
//@pv = previous value; @cv = current value
var reduced = list.reduce(function (pv, cv) {
    //slice keeps reference when element is an object/array
    var last = pv.slice(-1)[0];
    if (last === undefined) return [cv];
    //compares the id
    if (last[0] == cv[0]) 
        last[2] = +last[2] + (+cv[2]); //sums values
    else pv.push(cv); //order elements
    return pv;
}, []); //[] initial value for @pv

console.log(reduced);

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.