Elixir 簡明筆記(七)--- 列表

列表是Elixir中重要的數(shù)據(jù)結(jié)構(gòu)。相信其他編程語言中也有類似列表的結(jié)構(gòu)。Lisp的命名來自對列表的處理。在C,Java語言中,列表類似數(shù)組結(jié)構(gòu)。Elixir的列表遠比數(shù)組強大,它更像高級語言python的列表。

列表的定義

Elixir中使用方括號[]定義一個列表,列表的元素可以是任意Elixir類型,列表可以沒有元素,即空表,也可以是任意多個元素。列表還可以去嵌套。


iex(1)> l = []
[]
iex(2)> is_list l
true
iex(3)> l1 = [1, 2, :hello, "word", [1, 3]]
[1, 2, :hello, "word", [1, 3]]
iex(4)>

head和tail

Elixir列表是一個的存儲結(jié)構(gòu)是鏈表。也就是說,當你訪問列表的第一個元素的時候,速度會很快。但是要訪問其中的某個元素,將會帶來比較大的開銷。因為訪問n個元素的時候,必須先遍歷n-1個元素。

因此,由于列表的第一個元素比較特殊,訪問數(shù)獨快嘛。就單獨給了它一個名字,列表頭(head),除了head之外,剩下的元素即位列表尾(tail)。只有一個元素的列表head就是那個元素,tail為空,空列表的沒有head和tail。Elixir提供了兩個內(nèi)置函數(shù)hd和tl分別訪問列表的head和tail。

iex(1)> l = [1, 2, 3, 4]
[1, 2, 3, 4]
iex(2)> hd l
1
iex(3)> tl l
[2, 3, 4]
iex(4)> hd []
** (ArgumentError) argument error
    :erlang.hd([])
iex(5)> tl []
** (ArgumentError) argument error
    :erlang.tl([])
iex(6)> hd [:sigle_element]
:sigle_element
iex(7)> tl [:sigle_element]
[]

|操作符

列表的head和tail十分重要。Elixir提供了一個操作符用于把head和tail連接起來。

iex(1)> head = 1
1
iex(2)> tail = [2, 3, 4]
[2, 3, 4]
iex(3)> [head | tail]
[1, 2, 3, 4]
iex(4)>

實際上,列表就是使用|遞歸定義的,之前我們寫的[]加元素,其實是列表定義的一個語法糖。

iex(1)> [1, 2, 3]
[1, 2, 3]
iex(2)> [3|[]]
[3]
iex(3)> [1|[2|[3|[]]]]
[1, 2, 3]

模式匹配

函數(shù)式語言最重要的是一個特性就是模式匹配。Elixir的列表也可以進行模式匹配。|既然可以連接列表的head和tail,實際上也是把列表分為head和tail。那么就可以使用模式匹配。這個技術(shù)很強大,尤其是在函數(shù)遞歸調(diào)用的時候。

iex(1)> l = [1, 2, 3, 4]
[1, 2, 3, 4]
iex(2)> [head|tail] = l
[1, 2, 3, 4]
iex(3)> head
1
iex(4)> tail
[2, 3, 4]

列表的操作符

列表可以通過++符號連接兩個列表,也可以通過--把列表進行相減。in判斷是否屬于成員。

iex> [ 1, 2, 3 ] ++ [ 4, 5, 6 ] 
[1, 2, 3, 4, 5, 6]
iex> [1, 2, 3, 4] -- [2, 4] 
[1, 3]
iex> 1 in [1,2,3,4]
true
iex> "wombat" in [1, 2, 3, 4]
false

列表還是元組

看起來|++都可以連接列表,但是在某些應(yīng)用場景還是有區(qū)別的:

iex(1)> l = [1, 2, 3]
[1, 2, 3]
iex(2)> [0] ++ l
[0, 1, 2, 3]
iex(3)> [0|l]
[0, 1, 2, 3]
iex(4)> l ++ [4]
[1, 2, 3, 4]

我們知道,列表是鏈表,訪問第一個元素很快,可是訪問列表中其他的元素會很慢。所以使用++的時候在末尾追加列表會很慢。需要訪問鏈表的最后一個元素,這就重建了原先的列表,讓原先列表的末尾元素指向那個新元素。

還記得元組么,元組的數(shù)據(jù)結(jié)構(gòu)是順序的線性表,元組在內(nèi)存中是連續(xù)存儲的。因此可以通過元素的下標訪問元組的元素,并且這樣的操作速度很快,但是元組在修改或添加元素時開銷很大,因為這些操作會在內(nèi)存中對元組的進行整體復(fù)制。

因此,選擇列表還是元組,本質(zhì)上是對順序線性表和線性鏈表的選擇。

函數(shù)式語言

本節(jié)只是對列表進行簡單的介紹。我們不止一次說過列表的強大,模式匹配配合列表將會是Elixir強大的表現(xiàn)力。此外,我們在介紹字典類型結(jié)構(gòu)的是時候,將會介紹鍵值列表。一種有鍵值對的列表。在介紹模塊,尤其是Enum模塊提供了對列表的操作。

到目前為止,我們希望函數(shù)式語言帶來不同的編程思想,Think Different。通過對前面的學(xué)習(xí)介紹,可以對Elixir和函數(shù)式編程語言有了比較感性的感覺??墒浅苏Z言的表達操作上與常見的編程語言有所不同,但也沒有太大的不同。為了解決這個疑惑,我們將會在下一節(jié)介紹所謂的函數(shù)式語言。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容