什么是javascript中的reduce的等效项

时间:2018-09-19 13:24:21

标签: javascript

我是最近转移到js方面的后端开发人员。我正在看一个教程,遇到了下面的代码。

clickCreate: function(component, event, helper) {
    var validExpense = component.find('expenseform').reduce(function (validSoFar, inputCmp) {
        // Displays error messages for invalid fields
        inputCmp.showHelpMessageIfInvalid();
        return validSoFar && inputCmp.get('v.validity').valid;
    }, true);
    // If we pass error checking, do some real work
    if(validExpense){
        // Create the new expense
        var newExpense = component.get("v.newExpense");
        console.log("Create expense: " + JSON.stringify(newExpense));
        helper.createExpense(component, newExpense);
    }
}

在这里,我试图对所发生的事情有很多了解,其中有一个叫做reduce的东西,另一个叫validSoFar的东西。我无法理解幕后发生的事情。 :-(

我确实得到了Java中完成的常规循环。

有人可以请大家照亮一下这里发生的事情。我应该在我的日常工作中经常使用它。

谢谢

3 个答案:

答案 0 :(得分:0)

此处的reduce函数迭代费用表的每个输入组件,并逐步映射到布尔值。如果您说三个输入均具有真正的有效性,那么reduce函数将返回:

  1. true && true,其中第一个为true的是传递给reduce的初始值。
  2. true && true,此处第一个为true的是先前结果的结果。
  3. true && true

在归约结束时,您只剩下一个布尔值,代表整个值的有效性,如果只有一个输入组件的有效性为false,则整个归约值将为false。这是因为validSoFar会跟踪总体有效性,并通过返回到目前为止该形式是否有效以及迭代中当前输入的有效性的复合值来进行变异。

答案 1 :(得分:0)

在那里使用reduce没有意义,并且在reduce中具有副作用。最好使用Array.prototype.filter获取所有无效的费用项目。

然后使用Array.prototype.forEach对每个无效项目产生副作用。然后,您可以检查无效费用项目数组的长度,以查看您输入的内容是否有效:

function(component, event, helper) {
  var invalidExpenses = component.find('expenseform').filter(
    function(ex){
      //return not valid (!valid)
      return !ex.get('v.validity').valid
    }
  );
  invalidExpenses.forEach(
    //use forEach if you need a side effect for each thing
    function(ex){
      ex.showHelpMessageIfInvalid();
    }
  );
  // If we pass error checking, do some real work
  if(invalidExpenses.length===0){//no invalid expense items
      // Create the new expense
      var newExpense = component.get("v.newExpense");
      console.log("Create expense: " + JSON.stringify(newExpense));
      helper.createExpense(component, newExpense);
  }
}

mdn documentation for Array.prototype.reduce有一个很好的描述和使用示例。

它应该接受一组事物并返回另一事物(可以是不同类型的事物)。但是您不会在reducer函数中发现任何副作用开始的示例。

答案 2 :(得分:0)

这是一个合理的等价物:

var validExpense = true;
var inputCmps = component.find('expenseform')
for (var i = 0; i < inputCmps.length; i++) {
    // Displays error messages for invalid fields
    inputCmp.showHelpMessageIfInvalid();
    if (!inputCmp.get('v.validity').valid) {
        validExpense = false;
    }
}
// Now we can use validExpense

说实话,这是reduce的一种奇怪用法,因为它不仅仅是将列表简化为单个值,还可以做更多的事情。还会在调用showHelpMessageIfInvalid()时产生副作用(大概)。

reduce的想法很简单。给定要一次折叠为一个值(相同或任何其他类型)的值的列表,您可以提供一个函数,该函数采用当前折叠值和下一个列表值并返回新的折叠值,然后提供一个初始折叠值,reduce通过调用函数以及每个连续的列表值和当前折叠值来组合它们。

例如,

var items = [
  {name: 'foo', price: 7,  quantity: 3},
  {name: 'bar', price: 5,  quantity: 5},
  {name: 'baz', price: 19, quantity: 1}
]

const totalPrice = items.reduce(
  (total, item) => total + item.price * item.quantity, // folding function
  0  // initial value
); //=> 65