Map (映射)
Map是一種類似於JS的Object或是Python的Dictionary的資料型態,其表示法是用%{}包裹,並且以key => value的寫法紀錄mapping的關係。
並且,在Map中的鍵值沒有順序前後關係,所以才會有下面這個範例的顯示跟輸入順序不同的情況,因為他們其實都是一樣的。
iex(1)> %{7 => "bob", 5 => "jack", "aaa" => "ccc"}
%{5 => "jack", 7 => "bob", "aaa" => "ccc"}
當Map中的key是Atom時,有一種簡化的表示形式 可以將原本的 :aaa => bbb 改寫為 aaa: bbb 的寫法,像%{a: 3, b: 7, w: 13}
其實就是 %{:a => 3, :b => 7, :w => 13}
。
另外,我們可以使用以下方式存許Map中的值:
iex(1)> data = %{7 => "bob", 5 => "jack", "aaa" => "ccc"}
%{5 => "jack", 7 => "bob", "aaa" => "ccc"}
iex(2)> data[7]
"bob"
iex(3)> data["ccc"]
nil
iex(4)> data["aaa"]
"ccc"
使用以上方式,可以發現在key值不存在時,回傳了nil。
有另一種方式是如下的寫法,可在key值為Atom時使用,但在key值不存在時會報錯。
iex(1)> data = %{name: "jack", age: 18}
%{age: 18, name: "jack"}
iex(2)> data.name
"jack"
iex(3)> data.job
** (KeyError) key :job not found in: %{age: 18, name: "jack"}
此外,Map也可使用下列方式,對已存在的鍵值做修改 (若不存在會報錯)。
data = %{name: "jack", age: 18}
%{data | name: "one"}
%{name: "jack", age: 18}
%{data | job: 3}
** (KeyError) key :three not found
Map vs Keyword List
如果在先前的文章中有看到Keyword List,也就是這個東西:[{name: "jack"}, {age: 18}, {job: "engineer"}]
你會發現,Keyword List這個在elixir中廣泛被使用的資料型態,其實跟 Map 有著極為相似的功能,甚至在許多時候,他們是能互相取代的。
但他們之間還是有一些差異,但影響他們使用場合的,我猜可能更多是源自於社群的習慣。
但大致上,Keyword List用於選項參數或需要鍵值保留順序時。若是結構化的數據存取,則可使用Map。
項目 | Keyword List | Map |
---|---|---|
Key是否可重複 | 是 | 否 |
有序 | 是 | 否 |
讀取 | 非常快 | 快 |
插入 | 慢 | 快 |