Unable to make native javascript reduce() function work

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/

Answers


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/


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


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);
    });
});

Need Your Help

How to hand off to another controller in CodeIgniter?

php codeigniter http-redirect

I'm new to CodeIgniter and have created a controller that talks to a few views and models.

Object expected Microsoft Jscript Runtime Error- Node js

javascript node.js

I am learning Node JS and I am getting Object expected at line number 1 Microsoft Jscript Runtime Error while running the code

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.