Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Elixir中生成运行总和或行总和_Elixir_List Comprehension - Fatal编程技术网

在Elixir中生成运行总和或行总和

在Elixir中生成运行总和或行总和,elixir,list-comprehension,Elixir,List Comprehension,鉴于: 如何获得行和:[3,6,9,…,x] 要使用哪个Enum函数,或者如何使用列表理解来保存一个运行总和,目前还不清楚。我想说,最可读的方法是: data = [[1,2,3, ..., n],[1,2,3, ..., n],[1,2,3, ..., n], ...] # List with N rows of equal length 对于N列表的情况,需要使用递归: data |> Enum.zip() |> Enum.map(fn {v1, v2} -> v1

鉴于:

如何获得行和:
[3,6,9,…,x]


要使用哪个
Enum
函数,或者如何使用列表理解来保存一个运行总和,目前还不清楚。我想说,最可读的方法是:

 data = [[1,2,3, ..., n],[1,2,3, ..., n],[1,2,3, ..., n], ...] 
# List with N rows of equal length

对于
N
列表的情况,需要使用递归:

data
|> Enum.zip()
|> Enum.map(fn {v1, v2} -> v1 + v2 end)    
#⇒ [2, 4, 6, ..., x]
在Erlang/Elixir中,将解决方案扩展到输入列表的最简单方法是递归地将任何内容简化为单个参数的情况。有[可能]许多方法可以重写上面的示例以更好地优化,但我明确地以最明显的方式编写了它


对于那些来自OO背景的人来说,更明显(但习惯上是错误的)方法是将
zip
map
元组映射到列表:

data = [[1,2,3],[1,2,3],[1,2,3]]

defmodule ListSum do
  def mapper([inner1 | [inner2 | rest]]) do
    reduced = inner1
              |> Enum.zip(inner2)
              |> Enum.map(fn {v1, v2} -> v1 + v2 end)
    mapper([reduced | rest])
  end
  def mapper([list]) when is_list(list), do: list
end

IO.inspect ListSum.mapper(data)
#⇒ [3, 6, 9]

基准: 结果:

defmodule ListSum do
  def mapper([inner1 | [inner2 | rest]]) do
    reduced = inner1
              |> Enum.zip(inner2)
              |> Enum.map(fn {v1, v2} -> v1 + v2 end)
    mapper([reduced | rest])
  end
  def mapper([list]) when is_list(list), do: list

  def ttler(data) do
    data
    |> Enum.zip()
    |> Enum.map(fn e -> e |> Tuple.to_list() |> Enum.sum() end)
  end
end

defmodule ListSumBench do
  use Benchfella

  @list Enum.to_list(1..1_000)
  @lists List.duplicate(@list, 1_000)

  bench "mapper" do
    ListSum.mapper @lists
  end

  bench "ttler" do
    ListSum.ttler @lists
  end
end

Enum.sum
Enum.reduce(&Kernel.++/2)
之间的差异是微不足道的,但是
sum
要快一点(比如3%)

我想说,最可读的方法是:

 data = [[1,2,3, ..., n],[1,2,3, ..., n],[1,2,3, ..., n], ...] 
# List with N rows of equal length

对于
N
列表的情况,需要使用递归:

data
|> Enum.zip()
|> Enum.map(fn {v1, v2} -> v1 + v2 end)    
#⇒ [2, 4, 6, ..., x]
在Erlang/Elixir中,将解决方案扩展到输入列表的最简单方法是递归地将任何内容简化为单个参数的情况。有[可能]许多方法可以重写上面的示例以更好地优化,但我明确地以最明显的方式编写了它


对于那些来自OO背景的人来说,更明显(但习惯上是错误的)方法是将
zip
map
元组映射到列表:

data = [[1,2,3],[1,2,3],[1,2,3]]

defmodule ListSum do
  def mapper([inner1 | [inner2 | rest]]) do
    reduced = inner1
              |> Enum.zip(inner2)
              |> Enum.map(fn {v1, v2} -> v1 + v2 end)
    mapper([reduced | rest])
  end
  def mapper([list]) when is_list(list), do: list
end

IO.inspect ListSum.mapper(data)
#⇒ [3, 6, 9]

基准: 结果:

defmodule ListSum do
  def mapper([inner1 | [inner2 | rest]]) do
    reduced = inner1
              |> Enum.zip(inner2)
              |> Enum.map(fn {v1, v2} -> v1 + v2 end)
    mapper([reduced | rest])
  end
  def mapper([list]) when is_list(list), do: list

  def ttler(data) do
    data
    |> Enum.zip()
    |> Enum.map(fn e -> e |> Tuple.to_list() |> Enum.sum() end)
  end
end

defmodule ListSumBench do
  use Benchfella

  @list Enum.to_list(1..1_000)
  @lists List.duplicate(@list, 1_000)

  bench "mapper" do
    ListSum.mapper @lists
  end

  bench "ttler" do
    ListSum.ttler @lists
  end
end

Enum.sum
Enum.reduce(&Kernel.++/2)
之间的差异是微不足道的,但是
sum
要快一点(比如3%)

问题在于:复制和重用代码很容易。。。但是理解它为什么有效,或者为什么这是一种显而易见的方式,并不是很清楚。我试图写一个描述性的“为什么”,但我有点不明白,这里什么是合适的措辞。我们有两个长度相同的列表,因此我想到了
Enum.zip/2
。现在我们有了一个元组列表,因此
Enum.map/2
。也许如果你在理解为什么会这样的过程中说明什么是一个阻碍因素,我可以更好地表达为什么。不,但我会更新N个列表的答案。为什么不只对N个列表这样做:
|>Enum.zip |>Enum.map(fn t->t |>Tuple.to | u list |>Enum.sum end)
?@Dogbert根据基准,递归速度比元组快4.5倍。到\u list/1。问题是:复制和重用代码很容易。。。但是理解它为什么有效,或者为什么这是一种显而易见的方式,并不是很清楚。我试图写一个描述性的“为什么”,但我有点不明白,这里什么是合适的措辞。我们有两个长度相同的列表,因此我想到了
Enum.zip/2
。现在我们有了一个元组列表,因此
Enum.map/2
。也许如果你在理解为什么会这样的过程中说明什么是一个阻碍因素,我可以更好地表达为什么。不,但我会更新N个列表的答案。为什么不只对N个列表这样做:
|>Enum.zip |>Enum.map(fn t->t |>Tuple.to | u list |>Enum.sum end)
?@Dogbert根据基准,递归比Tuple.to_list/1快4.5倍。