LoginSignup
6
1

リストをStream化する

Last updated at Posted at 2023-12-30

有限長のリストを,あたかも無限長のStreamであるかのように扱いたい時があったので,実装してみたところ,うまくいきましたので,ご報告します.

実装例

fn list, default_value ->
  Stream.unfold(list, fn
    [] -> {default_value, []}
    [h | t] -> {h, t}
  end)
end

使用例

iex> f = 
...>   fn list, default_value ->
...>     Stream.unfold(list, fn
...>       [] -> {default_value, []}
...>       [h | t] -> {h, t}
...>     end)
...>   end
#Function<41.105768164/2 in :erl_eval.expr/6>
iex> s = f.([1, 2], 0)
#Function<63.53678557/2 in Stream.unfold/2>
iex> Enum.take(s, 10)
[1, 2, 0, 0, 0, 0, 0, 0, 0, 0]
iex> s = f.([9, 8, 7, 6, 5, 4, 3, 2, 1], 0)
#Function<63.53678557/2 in Stream.unfold/2>
iex> Enum.take(s, 10)
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
iex> s = f.(9..1, 0)
#Function<63.53678557/2 in Stream.unfold/2>
iex> Enum.take(s, 10)
** (FunctionClauseError) no function clause matching in :erl_eval."-inside-an-interpreted-fun-"/1    
    
    The following arguments were given to :erl_eval."-inside-an-interpreted-fun-"/1:
    
        # 1
        9..1//-1
    
    (stdlib 5.2) :erl_eval."-inside-an-interpreted-fun-"/1
    (stdlib 5.2) erl_eval.erl:963: :erl_eval.eval_fun/8
    iex:3: (file)
    iex:3: (file)
iex> s = f.([:a, :b], :c)
#Function<63.53678557/2 in Stream.unfold/2>
iex> Enum.take(s, 10)
[:a, :b, :c, :c, :c, :c, :c, :c, :c, :c]
iex>
6
1
6

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
1