平均値を計算する異なる実施形態

5376 ワード

この文章の翻訳と大幅な削除はfive-ways-to-average-with-js-reduce/からです.
  • もし私たちが次の配列を持っているなら、需要はまずfoundをフィルタリングしてfalseのitemにしてから平均値を求めます.
    const victorianSlang = [
      {
        term: "doing the bear",
        found: true,
        popularity: 108
      },
      {
        term: "katterzem",
        found: false,
        popularity: null
      },
      {
        term: "bone shaker",
        found: true,
        popularity: 609
      },
      {
        term: "smothering a parrot",
        found: false,
        popularity: null
      }
      //……
    ];
  • 一般的に考えられる方法は以下の通りです.
  • 1、forサイクル(読み取り可能性が悪く、書き方が優雅ではない)
    let popularitySum = 0;
    let itemsFound = 0;
    const len = victorianSlang.length;
    let item = null;
    for (let i = 0; i < len; i++) {
      item = victorianSlang[i];
      if (item.found) {
        popularitySum = item.popularity + popularitySum;
        itemsFound = itemsFound + 1;
      }
    }
    const averagePopularity = popularitySum / itemsFound;
    console.log("Average popularity:", averagePopularity);
    2、filter/map/reduce分離機能を使用する(コードが非常に綺麗で、実際に開発してもっと使えるのはこの方式です.)
    // Helper functions
    // ----------------------------------------------------------------------------
    function isFound(item) {
      return item.found;
    }
    
    function getPopularity(item) {
      return item.popularity;
    }
    
    function addScores(runningTotal, popularity) {
      return runningTotal + popularity;
    }
    
    // Calculations
    // ----------------------------------------------------------------------------
    
    // Filter out terms that weren't found in books.
    const foundSlangTerms = victorianSlang.filter(isFound);
    
    // Extract the popularity scores so we just have an array of numbers.
    const popularityScores = foundSlangTerms.map(getPopularity);
    
    // Add up all the scores total. Note that the second parameter tells reduce
    // to start the total at zero.
    const scoresTotal = popularityScores.reduce(addScores, 0);
    
    // Calculate the average and display.
    const averagePopularity = scoresTotal / popularityScores.length;
    console.log("Average popularity:", averagePopularity);
    3、直列の方式を使う.第二の方法は問題がないです.ただ二つの中間変数が多くなりました.読むことができるという点では、私はやはりそれに傾いています.しかし、Fluent interface原則に基づく(https://en.wikipedia.org/wiki...関数を簡単に変更できます.
    // Helper functions
    // ---------------------------------------------------------------------------------
    function isFound(item) {
      return item.found;
    }
    
    function getPopularity(item) {
      return item.popularity;
    }
    
    // We use an object to keep track of multiple values in a single return value.
    function addScores({ totalPopularity, itemCount }, popularity) {
      return {
        totalPopularity: totalPopularity + popularity,
        itemCount: itemCount + 1
      };
    }
    
    // Calculations
    // ---------------------------------------------------------------------------------
    const initialInfo = { totalPopularity: 0, itemCount: 0 };
    const popularityInfo = victorianSlang
      .filter(isFound)
      .map(getPopularity)
      .reduce(addScores, initialInfo);
    const { totalPopularity, itemCount } = popularityInfo;
    const averagePopularity = totalPopularity / itemCount;
    console.log("Average popularity:", averagePopularity);
    4、関数プログラミング式.前の3つのタイプは仕事でよく使われていると信じています.この方式はreactを熟知している学生は決して珍しくないと思います.私たちはapiによってcomposeを使います.もし私達が自分に制限を設けたら、このような書き方を真似して実現してほしいですか?実際に開発しても意味がないかもしれません.jsの実現は一つだけではないと強調しました.
    // Helpers
    // ----------------------------------------------------------------------------
    const filter = p => a => a.filter(p);
    const map = f => a => a.map(f);
    const prop = k => x => x[k];
    const reduce = r => i => a => a.reduce(r, i);
    const compose = (...fns) => arg => fns.reduceRight((arg, fn) => fn(arg), arg);
    
    // The blackbird combinator.
    // See: https://jrsinclair.com/articles/2019/compose-js-functions-multiple-parameters/
    const B1 = f => g => h => x => f(g(x))(h(x));
    
    // Calculations
    // ----------------------------------------------------------------------------
    
    // We'll create a sum function that adds all the items of an array together.
    const sum = reduce((a, i) => a + i)(0);
    
    // A function to get the length of an array.
    const length = a => a.length;
    
    // A function to divide one number by another.
    const div = a => b => a / b;
    
    // We use compose() to piece our function together using the small helpers.
    // With compose() you read from the bottom up.
    const calcPopularity = compose(
      B1(div)(sum)(length),
      map(prop("popularity")),
      filter(prop("found"))
    );
    
    const averagePopularity = calcPopularity(victorianSlang);
    console.log("Average popularity:", averagePopularity);
    5、遍歴したのは一回だけです.上のいくつかの方法は実際に三回使いました.一度だけ遍歴できる方法がありますか?数学に関する知識は下の図のようにあります.とにかく一連の公式変換を経て、遍歴することができます.
    // Average function
    // ----------------------------------------------------------------------------
    
    function averageScores({ avg, n }, slangTermInfo) {
      if (!slangTermInfo.found) {
        return { avg, n };
      }
      return {
        avg: (slangTermInfo.popularity + n * avg) / (n + 1),
        n: n + 1
      };
    }
    
    // Calculations
    // ----------------------------------------------------------------------------
    
    // Calculate the average and display.
    const initialVals = { avg: 0, n: 0 };
    const averagePopularity = victorianSlang.reduce(averageScores, initialVals).avg;
    console.log("Average popularity:", averagePopularity);
    まとめ:数学がよくできて、コードの書き方が少ないです.