Elixir文件流重用/ fork

时间:2016-06-29 20:06:51

标签: elixir

我有一个非常大的csv文件,包含日期和整数。我需要为每个文件记录创建一个Ecto记录。问题是,需要根据相邻记录的日期之间的最小时间差来操纵整数。我一直试图将流处理到一个点,绑定到一个变量,然后将其用于两个不同的计算。但第二次计算得到一个空流。似乎任何访问流,删除我得到的任何东西。有没有办法重用/ fork / clone / dup /某个流?我知道RX流有这个概念。我试着用一些方法在一个链中做到这一点,但是空洞了。这基本上就是我尝试的流程:

def do_something(path) do
  {:ok, file} = File.open(path)
  stream = file
  |> IO.stream(:line)
  |> Stream.map(&String.split(&1, ","))

  dates = stream_to_dates(stream) # stream
  factor = dates_to_factor(dates) # float
  values = stream_to_values(stream, factor) # stream

  Stream.zip(dates, values)
end

我能够计算日期,然后计算因子,但在此之后,流和日期都是空流,因此值为空,因此zip为空......

1 个答案:

答案 0 :(得分:1)

您可以使用Stream.transform创建来自给定流的对的流:

def pairs(stream) do
  Stream.transform(stream, nil, fn(x, last) ->
    # The first element is the list of values to return at this point,
    # the second one is the new accumulator
    {[{last, x}], x}
  end)
  # Drop the first pair of {nil, something}
  |> Stream.drop(1)
end

然后:

iex(1)> 1..1000 |> Stream2.pairs |> Enum.take(5)
[{1, 2}, {2, 3}, {3, 4}, {4, 5}, {5, 6}]

然后,您应该能够在|> Stream.map(&String.split(&1, ","))之后使用对来获取相邻记录对。如果你需要更大的块,可以推广这个功能。