0

I'm trying to aggregate data using the reduce() function in javascript (similar to this question):

HTML

Product 1: <button id="product1">Add one</button>
Product 2: <button id="product2">Add one</button>

JS

$('button').on('click', function() {
            var pid = $(this).attr('id');

            cart[cart.length] = {id:pid, qty:1}

            var result = cart.reduce(function(res, obj) {
                    if (!(obj.id in res))
                        res.__array.push(res[obj.id] = obj);
                    else {
                        res[obj.id].qty += obj.qty;
                    }
                    return res;
                }, {__array:[]})

            console.log(result)
    });
});

I'm unable to make it work as the array being return doesn't contain the qty data. E.g.:

Object {__array: Array[1], product1: Object}
Object {__array: Array[1], product1: Object}
Object {__array: Array[2], product1: Object, product2: Object}

The result I'm looking for is more like:

Object {product1: 1}   //click on product1, quantity = 1
Object {product1: 2}   //click on product1 again, quantity = 1 + 1 = 2
Object {product1: 2, product2: 1}  //click on product2

What am I missing?

http://jsfiddle.net/C4WuG/4/

Community
  • 1
  • 1
greener
  • 4,989
  • 13
  • 52
  • 93

3 Answers3

0

That doesn't fix your issue with reduce, but reduce is not the right tool. May I suggest you a different approach for this? Here instead of looping over the whole cart each time a product is added, we simply keep the count in sync for each additions.

Here I assumed you were adding a single product at a time, but you could increment by product.qty instead if needed.

http://jsfiddle.net/C4WuG/6/

var cart = [], count = {};

$(document).ready(function () {

    $('button').on('click', function () {
        var pid = $(this).attr('id');

        cart.push({
            id: pid,
            qty: 1
        });

        count[pid] = (count[pid] || 0) + 1;

        console.log(count);
    });
});
plalx
  • 42,889
  • 6
  • 74
  • 90
0

A solution using .reduce(), I don't think it is the best way

var cart = new Array();

$(document).ready(function(){

    $('button').on('click', function() {
        var pid = $(this).attr('id');

        cart[cart.length] = {id:pid, qty:1}

        var result = cart.reduce(function(res, obj) {
            if(res.__array){
                res = {};
            }

            if(!res[obj.id]){
                res[obj.id] = {
                    qty: 0
                }
            }

            res[obj.id].qty += obj.qty;

            return res;
        }, {__array:[]})

        console.log(result)
    });
});

Demo: Fiddle

OR

A simpler one using .forEach()

var cart = new Array();

$(document).ready(function(){

    $('button').on('click', function() {
        var pid = $(this).attr('id');

        cart[cart.length] = {id:pid, qty:1}

        var result = {};
        cart.forEach(function(obj, index){
            if(!result[obj.id]){
                result[obj.id] = { qty: 0 }
            }
            result[obj.id].qty += obj.qty;
        });

        console.log(result)
    });
});

Demo: Fiddle

Arun P Johny
  • 384,651
  • 66
  • 527
  • 531
0

if you want output like Object {product1: 2, product2: 1} and using reduce method, try below . It passing initial value as {}

reduce method is syntax is like

[].reduce(
   function( previousValue, currentValue, index,  array ){},
   initialValue 
);

and our solution is

var cart = [];

$(document).ready(function(){

     $('button').on('click', function() {

            cart.push( { id:$(this).attr('id'), qty:1 } );

            var result = cart.reduce(function(res, obj) {

                if (!(obj.id in res )) {
                    res[obj.id] = 0
                }     

                return ( res[obj.id] += obj.qty ) && res ; 

            }, {} )

            console.log( result )
    });
});

and fiddle http://jsfiddle.net/C4WuG/8/

rab
  • 4,134
  • 1
  • 29
  • 42
  • @greener Your question not described this , I made answer as ur question! .. please update question and jsfiddle , so we can understand more about this `product didn't exist in cart prior` condition – rab Apr 20 '13 at 06:59