Enum
其常見用法見:https://cloud.tencent.com/developer/section/1116852
在sort時,如果要獲得穩定的排序結果,要使用<= 而不是 <。
?
Stream
Stream是延遲處理的,而Enum是貪婪的,則意味著傳給它一個收集,它會默默計算那個收集的所有內容。如:
[ 1, 2, 3, 4, 5] |> Enum.map(&(&1 * &1)) |> Enum.with_index |> Enum.map( fn {value, index} -> value - index end ) |> IO.inspect #=> [ 1, 3 ,7, 13, 21 ]#第一個map函數接受原始列表并生成一個新列表,其元素值是原來的平方。...如此下去最終生成了四個列表s = Stream.map [ 1, 3, 5, 7 ], &(&1 + 1) #s不是一個列表 Enum.to_list s #這樣使用 => [ 2, 4, 6 ,8 ]#我們通常這樣寫 [ 1, 2, 3, 4 ] |> Stream.map(&(&1 * &1)) |> Stream.map(&(&1 + 1)) |> Stream.filter( fn x -> rem(x, 2) == 1 end ) #rem求余 |> Enum.to_list #轉化為我們可見的
使用Stream沒有中間結果,但是運行速度慢了兩倍。適用于數據抵達的慢,但一直持續。使用Enum要等到所有數據到達后才能開始處理。使用流,只有有數據抵達就可以進行處理。
?
自定義流
Stream.cycle。它接受一個枚舉類型參數,并返回一個包含該枚舉類型參數元素的無限流。當到達結尾時會從頭開始
Stream.cycle(~w{ green white })
|> Enum.take(5) #green white green white green
Stream.repeatedly。接受一個函數,在需要更新時調用該函數
Stream.iterate。Stream.iterate( start_value, next_fun )生成一個無限流,第一個值是start_value,下一個值是調用next_fun函數以第一個值為參數生成的。
Stream.iterate(0, &(&1 + 1)) |> Enum.take(5) #[ 0, 1, 2, 3, 4]
Stream.unfold。使用前兩個參數計算下一個值
Stream.unfold({0 ,1}, fn (f1, f2) -> {f1, {f2, f1 + f2}} end ) |> Enum.take(8)#[ 0, 1 ,1, 2, 3, 5, 8, 13 ]
? Stream.resource。現在需要在流開始的時候才創建/讀取數據,而在流結束的時候需要關閉數據。Stream.resource第一個參數接受一個函數,它會返回值。第二個參數也是接受一個函數,函數接受第一個函數的返回值。第三個參數函數關閉相關資源。
Stream.resource(fn -> File.open("sample") end, fn file -> case IO.read(file, :line) doline when is_binary(line) -> { [line], file }_ -> { :halt, file }endend,fn file -> File.close!(file) end )
?
推導式
for x <- [1, 2, 3, 4, 5], do: x * xfor x <- [1, 2, 3, 4, 5], x < 4, do: x * x
如果有兩個生成器,則它們的操作是嵌套的。
for x <- [1, 2], y <- [5, 6], do: {x, y} #[ {1, 5}, {1, 6}, {2, 5}, {2, 6} ]
后面的生成器可以使用前面的變量。
min_maxes = [{1, 4}, {2, 3}, {10, 15}] for {min, max} <- min_maxes, n <- min..max, do: n#[1, 2, 3, 4, 2, 3 ,10, 11, 12, 13, 14, 15]
例(使用了兩個生成器和過濾器)。
first8 = [1, 2, 3, 4, 5, 6, 7, 8] for x <- first8, y <- first8, x >= y, rem(x*y, 10) == 0, do: {x, y} #x >= y 防止出現{2, 5}、{5, 2}
?
推導式處理二進制。推導式中的變量只在其內部有效。
for << ch <- "hello >>, do: ch #返回的是列表[104, 101, 108, 108, 111] iex顯示為 'hello' for << ch <- "hello" >>, do: <<ch>> #將編碼轉換為字符串 ["h", "e", ... ]
推導式的返回值可以被into 改變。
for x <- ~w{ cat dog }, into: Map.new, do: { x, String.upcase(x) } # %{"cat" => "CAT", "dog" => "DOG" }
?