无法使原生javascript reduce()函数工作

时间:2013-04-20 06:05:29

标签: javascript aggregate javascript-objects reduce

我正在尝试使用javascript中的reduce()函数聚合数据(类似于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)
    });
});

我无法使其正常工作,因为返回的数组不包含qty数据。 E.g:

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

我正在寻找的结果更像是:

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

我错过了什么?

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

3 个答案:

答案 0 :(得分:0)

这不能解决reduce的问题,但reduce不是正确的工具。我可以建议你采用不同的方法吗?每次添加产品时,我们不会在整个cart上进行循环,而是在每次添加时保持计数同步。

我假设您一次只添加一个产品,但如果需要,您可以增加product.qty

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

答案 1 :(得分:0)

使用.reduce()的解决方案,我不认为这是最好的方法

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

演示:Fiddle

OR

使用.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)
    });
});

演示:Fiddle

答案 2 :(得分:0)

如果您想要Object {product1: 2, product2: 1}之类的输出并使用reduce方法,请尝试以下操作。它将初始值传递为{}

reduce方法就像语法一样

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

我们的解决方案是

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

并摆弄http://jsfiddle.net/C4WuG/8/