JavaScript中你不知道的數(shù)學(xué)方法分享(非常實(shí)用)
JavaScript的Math對(duì)象包含了一些非常有用和強(qiáng)大的數(shù)學(xué)操作,可以在Web開發(fā)中使用,但它缺少了許多其他大多數(shù)編程語言提供的重要操作(比如Haskell,它具有大量這樣的操作)。
以下是每個(gè)操作的快速鏈接:
- Sum
- Product
- Odd and Even
- triangleNumber
- Factorial
- Factors
- isPrime
- Greatest Common Divisor
- Lowest Common Multiple
1.求和(Sum)
你可能還記得在學(xué)校中,“sum”是“add”的同義詞。例如,如果我們對(duì)數(shù)字1、2和3求和,實(shí)際上是指1 + 2 + 3。
我們的求和函數(shù)將涉及對(duì)數(shù)組中所有值進(jìn)行求和。
有兩種編寫這個(gè)函數(shù)的方式:我們可以使用for循環(huán),或者我們可以使用reduce函數(shù)。如果你想重新熟悉reduce函數(shù),你可以閱讀有關(guān)在JavaScript中使用map()和reduce()的文檔。
使用for循環(huán)的方式:
function sum(array){ let total = 0 for(let count = 0; count < array.length; count++){ total = total + array[count] } return total }
使用reduce函數(shù)的方式:
function sum(array){ return array.reduce((sum, number) => sum + number, 0) }
這兩個(gè)函數(shù)的工作方式完全相同(reduce函數(shù)只是一個(gè)內(nèi)置的for循環(huán)),并且在給定相同數(shù)組的情況下將返回相同的結(jié)果。但是,reduce函數(shù)更加簡(jiǎn)潔。
例如:
sum([1,2,3,4]) === 10 // 1 + 2 + 3 + 4 sum([2,4,6,8]) === 20 // 2 + 4 + 6 + 8
能夠?qū)σ唤M數(shù)字求和可能是JavaScript Math對(duì)象中最有用且最需要的“缺失”數(shù)學(xué)操作。再次強(qiáng)調(diào),求和函數(shù)可以作為一個(gè)很好的檢查工具。例如,在數(shù)獨(dú)游戲中,我們可以通過檢查列或行的總和是否為45(1 + 2 + 3 + 4 +…+ 9)來檢查用戶是否沒有重復(fù)的數(shù)字。該函數(shù)在在線購(gòu)物應(yīng)用程序中也非常適用,如果我們想要計(jì)算總賬單,假設(shè)所有價(jià)格都存儲(chǔ)在一個(gè)數(shù)組中。
以下是在購(gòu)物應(yīng)用程序示例中如何使用該函數(shù)的示例代碼:
const prices = [2.80, 6.10, 1.50, 1.00, 8.99, 2.99] function totalCost(prices){ return prices.reduce((sum, item) => sum + item, 0) }
2.乘積(Product)
我們的乘積函數(shù)將以與求和函數(shù)類似的方式工作,不同之處在于,我們將把列表中的所有數(shù)字相乘。
同樣地,我們可以幾乎與第一個(gè)求和函數(shù)一樣使用for循環(huán):
function product(array){ let total = 1 for(let count = 0; count < array.length; count++){ total = total * array[count] } return total }
請(qǐng)注意,我們使用1來初始化total變量,而不是0,否則最后得到的乘積將始終為0。
但是在這種情況下,reduce函數(shù)仍然適用,并且仍然是更簡(jiǎn)潔的編寫函數(shù)的方式:
function product(array){ return array.reduce((total, num) => total*num, 1) }
以下是一些示例代碼:
product([2,5,8,6]) === 480 // 2 x 5 x 8 x 6 product([3,7,10,2]) === 420 // 3 x 7 x 10 x 2
這個(gè)函數(shù)的用途可能看起來不明顯,但在進(jìn)行多個(gè)轉(zhuǎn)換的計(jì)算時(shí)非常有用。例如,如果你想找出十個(gè)蘋果包裝袋(每袋一公斤,售價(jià)1.50RMB)的美元價(jià)格,而不是進(jìn)行大量的乘法運(yùn)算,將所有的值存儲(chǔ)在一個(gè)數(shù)組中并使用剛剛編寫的乘積函數(shù)將更加高效。
數(shù)組的一個(gè)示例格式如下:
const pricePerKg = 1.50 const numberOfKg = 10 const conversionRate = 1.16 const conversion = [1.50, 10, 1.16] const USprice = product([pricePerKg,numberOfKg,conversionRate])
3.奇數(shù)和偶數(shù)
這些函數(shù)將接受一個(gè)數(shù)字作為參數(shù),可以是數(shù)組的長(zhǎng)度,根據(jù)該數(shù)字是奇數(shù)還是偶數(shù)返回true或false。
要判斷一個(gè)數(shù)字是否為偶數(shù),它必須能夠被2整除;而要判斷一個(gè)數(shù)字是否為奇數(shù),則相反,不能被2整除。這將是函數(shù)的關(guān)鍵部分。
例如,Haskell語言中內(nèi)置了這些函數(shù),這使得事情變得更加容易,尤其是可以直接編寫如下代碼:
even 29 << false odd 29 << true
另一方面,Ruby提供了這些函數(shù)作為方法。這樣編寫起來仍然更加容易:
29.even? << false 29.odd? << true
在JavaScript中,編寫這些函數(shù)的最簡(jiǎn)單方法是使用取余運(yùn)算符%。它返回一個(gè)數(shù)除以另一個(gè)數(shù)的余數(shù)。例如:
11 % 3 === 2 // 11 divide 3 === 3 remainder 2
下面是我們的偶數(shù)函數(shù)的一個(gè)示例:
function even(number){ return number % 2 === 0 }
正如我們所看到的,我們有一個(gè)接受數(shù)字作為參數(shù)的偶數(shù)函數(shù),并根據(jù)條件返回一個(gè)布爾值:
number % 2 === 0
當(dāng)這個(gè)數(shù)被2整除時(shí),如果余數(shù)等于零,我們就知道它是可以被2整除的,函數(shù)將返回true。例如:
even(6) === true even (9) === false
下面是我們的奇數(shù)函數(shù)的一個(gè)示例:
function odd(number){ return number % 2 !== 0 }
這兩個(gè)函數(shù)非常相似:都接受一個(gè)數(shù)字作為參數(shù),并根據(jù)條件返回一個(gè)布爾值:
number % 2 !== 0
如果將數(shù)字除以2的余數(shù)不等于零,那么這個(gè)數(shù)就是奇數(shù),函數(shù)將返回true。例如:
odd(7) === true odd(114) === false
能夠檢查一個(gè)數(shù)字是奇數(shù)還是偶數(shù)非常重要,而且非常簡(jiǎn)單。一開始可能并不顯得那么重要,但它可以作為一個(gè)很好的輸入驗(yàn)證技術(shù),例如對(duì)于數(shù)組長(zhǎng)度,或者僅僅通過檢查兩個(gè)玩家游戲的勝者來判斷。你可以追蹤已經(jīng)玩了多少回合,如果回合數(shù)是奇數(shù),玩家1獲勝,如果是偶數(shù),玩家2獲勝——假設(shè)第一回合計(jì)為1。
這兩個(gè)函數(shù)是可以互換使用的,我們很可能只需要使用其中一個(gè)。然而,擁有這兩個(gè)函數(shù)可以使在代碼中更容易跟蹤真值和假值邏輯,特別是在大塊的代碼中。
下面是我們?nèi)绾尉帉懮鲜鍪纠拇a:
function checkWinner(gamesPlayed){ let winner if(odd(gamesPlayed)){ winner = "player1" } else{ winner = "player2" } return winner }
4.三角數(shù)(Triangle Number)
三角數(shù)聽起來比它們實(shí)際上要復(fù)雜得多。它們只是某個(gè)數(shù)之前所有整數(shù)的和。
例如,這是第五個(gè)三角數(shù):5 + 4 + 3 + 2 + 1 = 15。
這與我們之前提到的數(shù)獨(dú)的例子有關(guān)。我們想要檢查所有數(shù)字是否唯一,我們可以通過檢查它們是否與1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9的結(jié)果相等來實(shí)現(xiàn)。這當(dāng)然就是第九個(gè)三角數(shù)!
當(dāng)然,我們可以使用for循環(huán)編寫這個(gè)函數(shù),像這樣:
function triangleNumber(number){ let sum = 0 for(let i=1; i < number + 1; i++){ sum = sum + i } return sum }
然而,這將是一個(gè)非常低效的決定,因?yàn)橛幸粋€(gè)非常簡(jiǎn)單的公式可以計(jì)算三角數(shù):0.5 x (number) x (number + 1)。
因此,我們的函數(shù)的最高效版本應(yīng)該是這樣的:
function triangleNumber(number){ return 0.5 * number * (number + 1) }
以下是一些我們?nèi)绾问褂盟氖纠a:
triangleNumber(7) === 28 // 0.5 x 7 x 8 triangleNumber(123) === 7626 // 0.5 x 123 x 124
5.階乘(Factorial)
一個(gè)自然數(shù)(大于0的任意整數(shù))的階乘是小于等于該數(shù)的所有數(shù)的乘積。例如:3的階乘(表示為3!)是3 x 2 x 1 = 6。
與求和和乘積函數(shù)類似,我們可以用兩種方式創(chuàng)建階乘函數(shù):使用for循環(huán)和使用遞歸。如果你之前沒有接觸過遞歸算法,它們本質(zhì)上是反復(fù)調(diào)用自身的函數(shù),直到達(dá)到一個(gè)“基本情況”。你可以在《函數(shù)式JavaScript中的遞歸》中了解更多關(guān)于它們的內(nèi)容。
下面是我們?nèi)绾问褂胒or循環(huán)創(chuàng)建階乘函數(shù)的方法:
function factorial(number){ let total = 1 for (let i = 1; i < number+1; i++){ total = total * i } return total }
該函數(shù)通過從1到給定的數(shù)字的循環(huán)遍歷(每次遞增)并將總數(shù)與每個(gè)數(shù)字相乘,最后返回最終的總數(shù)(即該數(shù)字的階乘)。
下面是我們?nèi)绾问褂眠f歸創(chuàng)建階乘函數(shù)的方法:
function factorial(number){ if (number <= 0){ return 1 } else{ return number * factorial(number - 1) } }
在這個(gè)函數(shù)中,我們的基本情況是0,因?yàn)?的階乘令人驚訝地是1(這個(gè)證明實(shí)際上非常有趣)。這意味著,當(dāng)數(shù)字通過函數(shù)時(shí),只要它不為零,它將乘以factorial(number - 1)。
為了更好地理解函數(shù)在每次傳遞時(shí)的具體操作,跟蹤算法可能會(huì)有所幫助。下面是使用3跟蹤算法的示例:
factorial(3) === 3*factorial(2) === 3*2*factorial(1) === 3*2*1*factorial(0) === 3*2*1*1 === 3*2*1 === 6
無論哪種方式,這兩個(gè)函數(shù)都會(huì)返回相同的值。例如:
factorial(5) === 120 // 5 x 4 x 3 x 2 x 1
6.因子(Factors)
因子是成對(duì)出現(xiàn)的,每一對(duì)因子相乘得到原始數(shù)字。例如:
數(shù)字10的因子有:1和10;2和5。
數(shù)字18的因子有:1和18;2和9;3和6。
我們希望我們的因子函數(shù)接受一個(gè)數(shù)字,并返回一個(gè)包含所有因子的數(shù)組。有許多方法可以編寫這個(gè)函數(shù),但最簡(jiǎn)單的方法是使用命令式的方法,例如這樣:
function factors(number){ let factorsList = [] for(let count = 1; count < number+1; count++){ if(number % count === 0){ factorsList.push(count) } } return factorsList }
首先,我們創(chuàng)建一個(gè)數(shù)組,初始為空。然后我們使用一個(gè)for循環(huán)來遍歷從1到給定數(shù)字的每個(gè)整數(shù),每次遍歷時(shí)我們檢查數(shù)字是否可被整數(shù)(或在這種情況下的計(jì)數(shù)器)整除。
如你所見,為了檢查可被整除性,我們?cè)俅问褂昧四_\(yùn)算符。如果數(shù)字可被整數(shù)整除,則它是一個(gè)因子,并可以添加到我們的數(shù)組中。
然后返回該數(shù)組,每次運(yùn)行函數(shù)時(shí),將返回一個(gè)升序排列的因子數(shù)組。例如:
factors(50) === [1,2,5,10,25,50]
找出一個(gè)數(shù)字的因子在許多情況下非常有用,特別是當(dāng)你需要組織分組時(shí),比如在線游戲中,當(dāng)你需要每個(gè)隊(duì)伍都有相等數(shù)量的玩家。例如,如果你有20個(gè)玩家,每個(gè)隊(duì)伍需要10個(gè)玩家,你可以使用因子函數(shù)將10個(gè)玩家分配到兩個(gè)隊(duì)伍中。同樣地,如果每個(gè)隊(duì)伍需要4個(gè)玩家,你可以使用因子函數(shù)將4個(gè)玩家分配到五個(gè)隊(duì)伍中。
在實(shí)際應(yīng)用中,可能如下所示:
function createTeams(numberOfPlayers, numberOfTeams){ let playersInEachTeam if(factors(numberOfPlayers).includes(numberOfTeams)){ playersInEachTeam = numberOfPlayers / numberOfTeams } else{ playersInEachTeam = "wait for more players" } return playersInEachTeam }
7.isPrime(是否為素?cái)?shù))
這是學(xué)校中最早學(xué)到的條件之一,但在日常生活中很少使用。簡(jiǎn)而言之,如果一個(gè)數(shù)有兩個(gè)不同的因子,而這兩個(gè)因子分別為1和它本身,那么這個(gè)數(shù)就是素?cái)?shù)。素?cái)?shù)從2開始:2、3、5、7、11、13、17、19......一直延伸到無窮大。
這個(gè)函數(shù)可能一開始看起來很復(fù)雜,但如果我們剛剛寫過一個(gè)非常有用的因子函數(shù),它實(shí)際上會(huì)變得非常簡(jiǎn)單。如前所述,如果一個(gè)數(shù)有兩個(gè)不同的因子,那么它就是素?cái)?shù),因此我們的函數(shù)可以簡(jiǎn)單地寫為:
function isPrime(number){ return factors(number).length === 2 }
該函數(shù)將根據(jù)因子列表的長(zhǎng)度是否為2返回一個(gè)布爾值,換句話說,它將返回該數(shù)字是否有兩個(gè)因子。
實(shí)際應(yīng)用時(shí),它會(huì)像這樣:
isPrime(3) === true isPrime(76) === false isPrime(57) === true
在上面的“分組用戶”示例中繼續(xù),如果用戶數(shù)量是素?cái)?shù),我們無法平均分組(除非我們只有一個(gè)組,但這會(huì)違背示例的目的),這意味著我們必須等待另一個(gè)用戶加入。因此,我們可以在這樣的函數(shù)中使用它:
function addUsers(users){ if(isPrime(users)){ wait = true } else{ wait = false } }
8.gcd(最大公約數(shù))
有時(shí)被稱為“最高公因數(shù)”,最大公約數(shù)操作找到兩個(gè)數(shù)共有的最大因數(shù)。
例如:
12和15的最大公約數(shù)是3
8和4的最大公約數(shù)是4。
一種簡(jiǎn)單的方法是列出每個(gè)數(shù)的所有因數(shù)(使用上面提到的令人難以置信的函數(shù)),然后比較這些列表。然而,比較這些列表需要一些巧妙但也不太高效的數(shù)組操作。
不過,下面仍然是一個(gè)示例:
function gcd(number1, number2){ let inCommon = [] for(let i of factors(number1)){ if(factors(number2).includes(i)){ inCommon.push(i) } } return inCommon.sort((a,b)=> b - a)[0] }
這里,我們將一個(gè)空數(shù)組賦給變量inCommon,并循環(huán)遍歷number1的因數(shù)數(shù)組(使用之前的函數(shù))。如果number2的因數(shù)數(shù)組包含當(dāng)前遍歷的項(xiàng),我們將其推入inCommon數(shù)組中。
一旦我們獲得了兩個(gè)數(shù)共有的因數(shù)數(shù)組,我們返回?cái)?shù)組中按降序排序的第一個(gè)值。換句話說,我們返回最大公約數(shù)。
可以想象,如果我們沒有之前創(chuàng)建的factors函數(shù),這個(gè)代碼會(huì)很龐大。
一種更簡(jiǎn)潔但更難的方法是使用遞歸。這是一個(gè)相當(dāng)著名的算法,被稱為歐幾里得算法:
function gcd(number1, number2){ if(number2 === 0){ return number1 } else{ return gcd(number2, number1%number2) } }
我們的基本情況是當(dāng)number2等于0時(shí),此時(shí)number1就是最大公約數(shù)。否則,最大公約數(shù)是number2和number1除以number2的余數(shù)的最大公約數(shù)。
同樣,這兩個(gè)函數(shù)都會(huì)返回相同的結(jié)果。例如:
gcd(24, 16) === 8 gcd(75, 1) === 1
最小公倍數(shù)(LCM)是找出兩個(gè)或多個(gè)數(shù)能夠整除的最小的正整數(shù)。
例如:
2和6的最小公倍數(shù)是6。 4和15的最小公倍數(shù)是60。 不幸的是,我們不能簡(jiǎn)單地列舉出每個(gè)數(shù)的所有倍數(shù),因?yàn)檫@將是一個(gè)無限列表。
然而,我們可以使用一個(gè)非常有用的公式來計(jì)算最小公倍數(shù):
(number1 x number2) / the Greatest Common Divisor of the two numbers
使用公式計(jì)算2和6的最小公倍數(shù)(LCM)的步驟如下:
- 找到兩個(gè)數(shù)的最大公約數(shù)(GCD)。在這種情況下,2和6的最大公約數(shù)是2。
- 將兩個(gè)數(shù)相乘并除以它們的最大公約數(shù)。在這種情況下,2乘以6除以2等于6。
因此,2和6的最小公倍數(shù)(LCM)是6。
(2 x 6)/gcd(2,6) = 12/2 = 6
幸運(yùn)的是,我們剛剛創(chuàng)建了一個(gè)gcd函數(shù),因此創(chuàng)建lcm函數(shù)非常容易:
function lcm(number1, number2){ return (number1*number2)/gcd(number1, number2) }
就這樣!我們只需要返回上面的公式,它應(yīng)該可以正常工作:
lcm(12, 9) === 36 // (12 x 9)/3
這個(gè)函數(shù)可能沒有明顯的實(shí)際用途,但在兩個(gè)事件以不同的間隔發(fā)生時(shí),我經(jīng)常發(fā)現(xiàn)它非常有用。這意味著我們可以使用最小公倍數(shù)(LCM)來找出兩個(gè)事件同時(shí)發(fā)生的時(shí)間。
例如,如果一個(gè)圖像被設(shè)置為每隔六秒出現(xiàn)一次,而一個(gè)段落的文本被設(shè)置為每隔八秒出現(xiàn)一次,那么在第24秒時(shí),圖像和段落將首次同時(shí)出現(xiàn)。
以上就是JavaScript中你不知道的數(shù)學(xué)方法分享(非常實(shí)用)的詳細(xì)內(nèi)容,更多關(guān)于JavaScript數(shù)學(xué)方法的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
layui輸入框中只允許輸入整數(shù)的實(shí)現(xiàn)方法
今天小編就為大家分享一篇layui輸入框中只允許輸入整數(shù)的實(shí)現(xiàn)方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-09-09基于javascript實(shí)現(xiàn)圖片左右切換效果
這篇文章主要為大家介紹了基于javascript實(shí)現(xiàn)圖片左右切換效果,感興趣的小伙伴們可以參考一下2016-01-01

微信小程序webview組件交互,內(nèi)聯(lián)h5頁面并網(wǎng)頁實(shí)現(xiàn)微信支付實(shí)現(xiàn)解析

JS發(fā)起HTTP請(qǐng)求的多種方式總結(jié)

javascript實(shí)現(xiàn)div的顯示和隱藏的小例子

js調(diào)用activeX獲取u盤序列號(hào)的代碼