亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

reduce 內部的累加器函數由 Javascript 中的函數使用閉包進行包裝

reduce 內部的累加器函數由 Javascript 中的函數使用閉包進行包裝

叮當貓咪 2022-08-18 10:01:43
var arr = [{ name: "John", score: "8.8" }, { name: "John", score: "8.6" }, { name: "John", score: "9.0" }, { name: "John", score: "8.3" }, { name: "Tom", score: "7.9" }],    avgScore = arr.reduce(function (sum, count) {        return function (avg, person) {            if (person.name === "John") {                sum += +person.score;                return sum / ++count;            }            return avg;        };    }(0, 0), 0);console.log(avgScore);我發現了這個有趣的代碼,我想知道閉包在Javascript中是如何工作的。令我吃驚的是,帶有累加器和迭代元素的函數被另一個函數包裝。reduce不應該接受帶有累加器和迭代元素的函數,那么為什么reduce函數仍然有效,盡管具有vave迭代元素的累加器函數被另一個函數包裝?另外,為什么我們使用(0,0)調用帶有閉包的函數,但是在第二次迭代中,我們使用更新的總和和計數(sum,1)來調用它。閉包不應該一遍又一遍地使用參數(0,0)嗎?
查看完整描述

2 回答

?
DIEA

TA貢獻1820條經驗 獲得超2個贊

這是一種非常模糊的使用方式。但是,它確實有效。reduce


立即調用 ,返回 ,然后由 每個元素使用,從累加器開始,并在每次迭代中返回一個新的平均值,即使實際上只使用了最后一個值。它的工作原理是更新每次迭代的閉包中的 和 變量。function (sum, count)(0,0)function (avg, person)reduce0sumcount


計算平均值的一種更具可讀性的方法是:reduce


const result = arr.reduce(function (acc, person) {

  if (person.name === "John") {

    return {

        sum: acc.sum + parseFloat(person.score),

        count: acc.count + 1

    }

  }

  return acc

}, { sum: 0, count: 0 })

console.log(result.sum / result.count)

但是,由于關鍵是計算一個人的平均分數,因此一種更具可讀性且更短的方法是:


const johnsScores = arr.filter(person => person.name === 'John')

const total = johnsScores.reduce((acc, person) => acc + parseFloat(person.score), 0)

console.log(total / johnsScores.length)


查看完整回答
反對 回復 2022-08-18
?
慕慕森

TA貢獻1856條經驗 獲得超17個贊

確定約翰的平均分數似乎有點復雜。它使用閉包來能夠有條件地遞增 的值。我試圖使用運行值的日志來解釋它。count


無論如何,平均確定可以大大簡化(請參閱代碼片段的第二部分)


const arr = [

  { name: "John", score: "8.8" },

  { name: "John", score: "8.6" },

  { name: "John", score: "9.0" },

  { name: "John", score: "8.3" },

  { name: "Tom", score: "7.9" } ];


// the outer function delivers the inner function

// the outer function uses 0, 0 as input initially

// The outer function does nothing with those values

// and it returns not a value, but the inner function.

// The inner function is run every iteration of reduce

// and in there the initial closed over values are 

// manipulated. That inner function returns the actual

// accumulator value (a running average)

const avgScoreDemo = arr.reduce(function(sum, count) {

  let outerValues = `outer sum: ${sum}, outer count: ${count}`;

  return function(avg, person) {

    console.log(outerValues +

      ` avg: ${avg}, inner sum ${sum}, inner count: ${count}`);

    if (person.name === "John") {

      sum += +person.score;

      return sum / ++count;

    }

    return avg;

  };

}(0, 0), 0);


// This can be simplified to

const avgScore = arr.reduce((sum, person) =>

    sum + (person.name === "John" ? +person.score : 0), 0) /

  arr.filter(v => v.name === "John").length;

console.log(avgScore);


// or using filter/index value

const avgScore2 = arr

  .filter( v => v.name === "John" )

  .reduce( (acc, person, i) =>

    ({ ...acc, sum: acc.sum + +person.score, 

        average: (acc.sum + +person.score) / ++i }), 

    { average: 0, sum: 0 } ).average;

console.log(avgScore2);

.as-console-wrapper {

  top: 0;

  max-height: 100% !important;

}


查看完整回答
反對 回復 2022-08-18
  • 2 回答
  • 0 關注
  • 143 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號