W3Cschool
恭喜您成為首批注冊(cè)用戶
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
在上述表達(dá)式中,n <- [1, 2, 3, 4]
是發(fā)生器.它會(huì)生成在推導(dǎo)式中使用的值.任何枚舉體都可以被傳送到發(fā)生器表達(dá)式的右邊:
iex> for n <- 1..4, do: n * n
[1, 4, 9, 16]
生成器表達(dá)式的左邊也支持模式匹配;所有不能匹配的都會(huì)被忽略.想象一下,表達(dá)式右邊不再是一個(gè)范圍,而是一個(gè)有著原子鍵:good
和:bad
的關(guān)鍵詞列表,而我們只想要計(jì)算:good
值的平方:
iex> values = [good: 1, good: 2, bad: 3, good: 4]
iex> for {:good, n} <- values, do: n * n
[1, 4, 16]
除了模式匹配之外,篩選器可以用于選擇一些特定的元素.例如,我們可以選出3的倍數(shù):
iex> multiple_of_3? = fn(n) -> rem(n, 3) == 0 end
iex> for n <- 0..5, multiple_of_3?.(n), do: n * n
[0, 9]
推導(dǎo)式將所有篩選器表達(dá)式結(jié)果為false
或nil
的元素過濾掉了;其它所有值都被選入.
推導(dǎo)式通常提供比使用Enum
和Stream
模塊中的相等函數(shù)更加簡(jiǎn)潔的表達(dá)方法.而且,推導(dǎo)式也允許指定多重生成器和篩選器.這里有一個(gè)例子,接收一個(gè)目錄組成的列表,然后得到這些目錄中每個(gè)文件的大小:
for dir <- dirs,
file <- File.ls!(dir),
path = Path.join(dir, file),
File.regular?(path) do
File.stat!(path).size
end
多重發(fā)生器也可以用于計(jì)算兩個(gè)列表的笛卡爾乘積:
iex> for i <- [:a, :b, :c], j <- [1, 2], do: {i, j}
[a: 1, a: 2, b: 1, b: 2, c: 1, c: 2]
一個(gè)更好的關(guān)于多重發(fā)生器和篩選器的案例是勾股數(shù).勾股數(shù)是指滿足a*a + b*b = c*c
的正整數(shù),讓我們?cè)谖募?code>triple.exs中編寫一個(gè)推導(dǎo)式:
defmodule Triple do
def pythagorean(n) when n > 0 do
for a <- 1..n,
b <- 1..n,
c <- 1..n,
a + b + c <= n,
a*a + b*b == c*c,
do: {a, b, c}
end
end
然后在終端中運(yùn)行:
iex triple.exs
iex> Triple.pythagorean(5)
[]
iex> Triple.pythagorean(12)
[{3, 4, 5}, {4, 3, 5}]
iex> Triple.pythagorean(48)
[{3, 4, 5}, {4, 3, 5}, {5, 12, 13}, {6, 8, 10}, {8, 6, 10}, {8, 15, 17},
{9, 12, 15}, {12, 5, 13}, {12, 9, 15}, {12, 16, 20}, {15, 8, 17}, {16, 12, 20}]
當(dāng)搜索范圍是一個(gè)巨大的數(shù)時(shí),上述代碼會(huì)非常昂貴.此外,由于{b, a, c}
和{a, b, c}
是相同的勾股數(shù),所以我們的函數(shù)生成重復(fù)結(jié)果.我們可以優(yōu)化推導(dǎo)式來消除重復(fù)的結(jié)果,即在后面引用先前發(fā)生器中的變量,例如:
defmodule Triple do
def pythagorean(n) when n > 0 do
for a <- 1..n-2,
b <- a+1..n-1,
c <- b+1..n,
a + b + c <= n,
a*a + b*b == c*c,
do: {a, b, c}
end
end
最后,記住推導(dǎo)式內(nèi)部的變量賦值,即發(fā)生器,篩選器或塊內(nèi)的,不會(huì)影響到推導(dǎo)式的外部.
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: