W3Cschool
恭喜您成為首批注冊(cè)用戶(hù)
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
讓我們看看如何利用遞歸的力量來(lái)計(jì)算一個(gè)列表的數(shù)字之和:
defmodule Math do
def sum_list([head | tail], accumulator) do
sum_list(tail, head + accumulator)
end
def sum_list([], accumulator) do
accumulator
end
end
IO.puts Math.sum_list([1, 2, 3], 0) #=> 6
我們以列表[1, 2, 3]
和初始值0
為參數(shù)調(diào)用了sum_list
。我們將逐個(gè)嘗試從句,直到模式匹配成功。這個(gè)案例中,列表[1 ,2, 3]
匹配了[head | tail]
,head
對(duì)應(yīng)著1
而tail
對(duì)應(yīng)著[2, 3]
;accumulator
設(shè)置成0
。
接著,我們將列表的頭與收集器相加head + accumulator
,并將列表的尾作為第一個(gè)參數(shù)再次調(diào)用sum_list
。尾會(huì)再次匹配[head | tail]
直到列表變空:
sum_list [1, 2, 3], 0
sum_list [2, 3], 1
sum_list [3], 3
sum_list [], 6
當(dāng)列表為空時(shí),將匹配最后的從句,返回最終結(jié)果?6
?。
將一個(gè)列表歸約成一個(gè)值的過(guò)程叫做歸約算法,它是函數(shù)式編程的中心。
如果我們想將列表中所有值翻倍呢?
defmodule Math do
def double_each([head | tail]) do
[head * 2 | double_each(tail)]
end
def double_each([]) do
[]
end
end
iex math.exs
iex> Math.double_each([1, 2, 3]) #=> [2, 4, 6]
這里我們使用遞歸來(lái)遍歷列表,將每個(gè)元素翻倍并返回一個(gè)新的列表。將一個(gè)列表映射到一個(gè)新列表的過(guò)程叫做映射算法。
遞歸和尾調(diào)用是Elixir中的重要部分,且常用于創(chuàng)建環(huán)。然而在實(shí)際使用Elixir時(shí),你很少會(huì)像上面那樣用遞歸來(lái)操作列表。
下一章我們將看到的?Enum
?模塊,已經(jīng)提供了許多用于操作列表的便捷方法。實(shí)際中,上述例子可以寫(xiě)成:
iex> Enum.reduce([1, 2, 3], 0, fn(x, acc) -> x + acc end)
6
iex> Enum.map([1, 2, 3], fn(x) -> x * 2 end)
[2, 4, 6]
或者使用捕獲語(yǔ)法:
iex> Enum.reduce([1, 2, 3], 0, &+/2)
6
iex> Enum.map([1, 2, 3], &(&1 * 2))
[2, 4, 6]
讓我們進(jìn)一步觀察Enumerable
以及它懶惰的相對(duì)物Stream
。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話(huà):173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: