javascript减少不在对象上工作

时间:2018-01-28 18:53:19

标签: javascript reduce

我想了解减少的工作原理

var expense = [
        {
            item: 'Bed',
            cost: 1499,
            date: '02-23-2018'
        },
        {
            item: 'Phone',
            cost: 2499,
            date: '02-23-2018'
        },
        {
            item: 'Book',
            cost: 400,
            date: '02-23-2018'
        },
        {
            item: 'Mattress',
            cost: 700,
            date: '02-23-2018'
        },
        {
            item: 'Food',
            cost: 300,
            date: '02-23-2018'
        }
    ];

    var totalExpense = expense.reduce(function(a,b){
        console.log(a.cost, b.cost);
        return a.cost + b.cost;
    });

    console.log(totalExpense);

这使得totalExpense成为NaN。

输出: -

1499 2499
undefined 400
undefined 700
undefined 300
NaN

当我使用简单的费用数组执行相同的操作时,它可以正常工作。

6 个答案:

答案 0 :(得分:5)

传递给reduce回调的第一个参数是前一个值(a) - 或者你传递给reduce的第二个参数(初始值)

[].reduce(function(a, b) { ... }, 0);
          ^ callback              ^ initial value

a将保留上一次迭代的结果,因此要获得所有费用的总和,只需添加b.cost

var expense = [{
    item: 'Bed',
    cost: 1499,
    date: '02-23-2018'
  },
  {
    item: 'Phone',
    cost: 2499,
    date: '02-23-2018'
  },
  {
    item: 'Book',
    cost: 400,
    date: '02-23-2018'
  },
  {
    item: 'Mattress',
    cost: 700,
    date: '02-23-2018'
  },
  {
    item: 'Food',
    cost: 300,
    date: '02-23-2018'
  }
];
var totalExpense = expense.reduce(function(a, b) {
  return a + b.cost;
}, 0);

console.log(totalExpense);

使用es6语法可以使它成为一个单一的

var totalExpense = expense.reduce((a, {cost}) => a + cost, 0);

答案 1 :(得分:0)

您需要提供一个具有cost字段的初始值,以便在累加器中引用它。你需要返回那个对象:

expense.reduce(function(acc, curr){
    console.log(acc.cost, curr.cost);
    acc.cost += curr.cost;
    return acc;
    }, { cost: 0 });

请注意使用比ab更有意义的变量名称。这将使您的代码更容易理解。 Array.prototype.reduce回调应该有一个累加器和当前值。将它们命名为可以帮助自己。初始值为对象提供cost字段,您可以在其中记下累计值。

请注意,如果您愿意,也可以在此处使用vanilla变量。如果您实际上不需要对象:

var total = expense.reduce(function(acc, curr){
    acc += curr.cost;
    return acc;
    }, 0);
 console.log(total);
 >> 5398

答案 2 :(得分:0)

您需要blob下一个return应该是什么。 a是一个数字。它没有a.cost + b.cost属性,因此cost在第一次迭代后将为a.cost

只需提供一个起始值undefined。另外,请考虑为您的参数指定更合适的名称。

0

答案 3 :(得分:0)

您需要一个初始值。 reduce函数将累计值作为第一个参数,将集合的下一个元素作为第二个

RemoteDataError: Unable to read URL: http://www.google.com/finance/historical?q=F&startdate=Jan+01%2C+2010&enddate=Jan+27%2C+2013&output=csv

答案 4 :(得分:0)

expense.reduce((sum, cur) => ({ cost: sum.cost + cur.cost })).cost;

答案 5 :(得分:-1)

以下是使用通用函数foldMap执行此操作的另一种方法 - 有关此美丽函数的更多指导,我建议使用this video

const totalExpense =
  expense.foldMap (item => item.cost, 0)

console.log (totalExpense)
// 5398

为此,您需要定义Array.prototype.foldMapNumber.prototype.concat - 但此实现及其定义取决于您

Array.prototype.foldMap = function (f, acc)
{
  return this.reduce ((acc, x, i) =>
    acc.concat (f (x, i, this)), acc)
}

Number.prototype.concat = function (m)
{
  return this + m
}

这是一个正常运行的代码粘贴

Array.prototype.foldMap = function (f, acc)
{
  return this.reduce ((acc, x, i) =>
    acc.concat (f (x, i, this)), acc)
}

Number.prototype.concat = function (m)
{
  return this + m
}

const expense =
  [ { item: 'Bed'
    , cost: 1499
    , date: '02-23-2018'
    }
  , { item: 'Phone'
    , cost: 2499
    , date: '02-23-2018'
    }
  , { item: 'Book'
    , cost: 400
    , date: '02-23-2018'
    }
  , { item: 'Mattress'
    , cost: 700
    , date: '02-23-2018'
    }
  , { item: 'Food'
    , cost: 300
    , date: '02-23-2018'
    }
  ]
  
const totalExpense =
  expense.foldMap (item => item.cost, 0)

console.log(totalExpense)
// 5398