摘要:本文翻譯并嚴(yán)重刪減自如果我們有以下數(shù)組需求是先過濾掉為的再計(jì)算求平均值一般想到的方法不外乎是一下幾種循環(huán)可閱讀性差,寫法并不優(yōu)雅使用分離功能代碼非常干凈,實(shí)際開發(fā)我們更多可能用的是這種方式使用串聯(lián)的方式。
本文翻譯并嚴(yán)重刪減自five-ways-to-average-with-js-reduce/
如果我們有以下數(shù)組:需求是先過濾掉 found 為 false 的 item 再計(jì)算求平均值
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 循環(huán) (可閱讀性差,寫法并不優(yōu)雅)
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 分離功能(代碼非常干凈,實(shí)際開發(fā)我們更多可能用的是這種方式)
// 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、 使用串聯(lián)的方式。第二種方式并沒有什么問題,只是多了兩個(gè)中間變量,在可閱讀性上我還是更傾向于它。但基于Fluent interface原則(https://en.wikipedia.org/wiki...,我們可以簡單改一下函數(shù)
// 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、函數(shù)編程式。前面三種相信在工作中是很常用到的,這一種方式熟悉 react 的同學(xué)肯定不陌生,我們會(huì)根據(jù) api 去使用 compose。如果我們給自己設(shè)限,要求模仿這種寫法去實(shí)現(xiàn)呢?強(qiáng)調(diào)下在實(shí)際開發(fā)中可能并沒有什么意義,只是說明了 js 的實(shí)現(xiàn)不止一種。
// 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、只有一次遍歷的情況。上面幾種方法實(shí)際上都用了三次遍歷。如果有一種方法能夠只遍歷一次呢?需要了解一點(diǎn)數(shù)學(xué)知識(shí)如下圖,總之就是經(jīng)過一系列的公式轉(zhuǎn)換可以實(shí)現(xiàn)一次遍歷。
// 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);
總結(jié):數(shù)學(xué)學(xué)得好,代碼寫得少
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/104841.html
摘要:簡單模式記錄多個(gè)累加值在之前的版本中,我們創(chuàng)建了很多中間變量,。接下來,我們給自己設(shè)一個(gè)挑戰(zhàn),使用鏈?zhǔn)讲僮鳎瑢⑺械暮瘮?shù)調(diào)用組合起來,不再使用中間變量。你甚至可以繼續(xù)簡化上述代碼,移除不必要的中間變量,讓最終的計(jì)算代碼只有一行。 譯者按: 有時(shí)候一個(gè)算法的直觀、簡潔、高效是需要作出取舍的。 原文: FUNCTIONAL JAVASCRIPT: FIVE WAYS TO CALCULA...
摘要:上一個(gè)筆記主要是講了的原理,并給出了二維圖像降一維的示例代碼。當(dāng)我使用這種方法實(shí)現(xiàn)時(shí),程序運(yùn)行出現(xiàn)錯(cuò)誤,發(fā)現(xiàn)是對負(fù)數(shù)開平方根產(chǎn)生了錯(cuò)誤,也就是說對協(xié)方差矩陣求得的特征值中包含了負(fù)數(shù)。而能夠用于任意乘矩陣的分解,故適用范圍更廣。 上一個(gè)筆記主要是講了PCA的原理,并給出了二維圖像降一維的示例代碼。但還遺留了以下幾個(gè)問題: 在計(jì)算協(xié)方差和特征向量的方法上,書上使用的是一種被作者稱為com...
摘要:數(shù)據(jù)規(guī)整化清理轉(zhuǎn)換合并重塑數(shù)據(jù)聚合與分組運(yùn)算數(shù)據(jù)規(guī)整化清理轉(zhuǎn)換合并重塑合并數(shù)據(jù)集可根據(jù)一個(gè)或多個(gè)鍵將不同中的行鏈接起來。函數(shù)根據(jù)樣本分位數(shù)對數(shù)據(jù)進(jìn)行面元?jiǎng)澐帧W值浠颍o出待分組軸上的值與分組名之間的對應(yīng)關(guān)系。 本篇內(nèi)容為整理《利用Python進(jìn)行數(shù)據(jù)分析》,博主使用代碼為 Python3,部分內(nèi)容和書本有出入。 在前幾篇中我們介紹了 NumPy、pandas、matplotlib 三個(gè)...
摘要:爬蟲敏感圖片的識(shí)別與過濾,了解一下需求我們需要識(shí)別出敏感作者的頭像把皮卡丘換成優(yōu)雅的。對比哈希不同圖片對比的方法,就是對比它們的位哈希中,有多少位不一樣漢明距離。 爬蟲敏感圖片的識(shí)別與過濾,了解一下? 需求 我們需要識(shí)別出敏感作者的avatar頭像,把皮卡丘換成優(yōu)雅的python。 敏感圖片樣本屬性: showImg(https://ws3.sinaimg.cn/large/006tN...
摘要:需要對個(gè)人的日語元音的發(fā)音分析,然后根據(jù)分析確定名發(fā)音者。九個(gè)發(fā)音者發(fā)出兩個(gè)日本元音先后。其中每塊數(shù)據(jù)中包含的行數(shù)為到不等,每行代表著發(fā)音者的一個(gè)時(shí)間幀。 業(yè)務(wù)理解(Business Understanding) 該業(yè)務(wù)是分類問題。需要對9個(gè)人的日語元音ae的發(fā)音分析,然后根據(jù)分析確定9名發(fā)音者。ae.train文件是訓(xùn)練數(shù)據(jù)集,ae.test文件是用來測試訓(xùn)練效果的,size_ae...
閱讀 1618·2021-11-22 13:53
閱讀 2848·2021-11-15 18:10
閱讀 2755·2021-09-23 11:21
閱讀 2491·2019-08-30 15:55
閱讀 475·2019-08-30 13:02
閱讀 752·2019-08-29 17:22
閱讀 1659·2019-08-29 13:56
閱讀 3455·2019-08-29 11:31