erlang 我怎样才能打破一个枚举.减少在 Elixir

5rgfhyps  于 2023-02-20  发布在  Erlang
关注(0)|答案(4)|浏览(245)

我想求第一个负数之前所有正数的和

我在 Elixir 里找到了下面的名单。

iex(4)> steps = [0,1,2,3,-4,5,6,-1]

我计算这个列表的总和如下

Enum.reduce(steps,0,fn x,acc -> acc=acc+x end)

如果遇到负数,如何从reduce中出来?

vaj7vani

vaj7vani1#

使用Enum.reduce_whilehttps://hexdocs.pm/elixir/Enum.html#reduce_while/3

[1,2,3,-4,5,6,-1] |> Enum.reduce_while(0, fn x, acc ->
   if x > 0, do: {:cont, acc + x}, else: {:halt, acc}
end )
efzxgjgh

efzxgjgh2#

可以使用Enum.take_while/2https://hexdocs.pm/elixir/Enum.html#take_while/2
从可枚举对象的开头获取项,而fun返回真实值。

Enum.take_while([0, 1, 2, 3, -4, 5, 6, -1], fn(x) -> x >= 0 end) |> Enum.sum

=> 6

或者用速记

list = [0, 1, 2, 3, -4, 5, 6, -1]
Enum.take_while(list, &(&1 >= 0)) |> Enum.sum
ipakzgxi

ipakzgxi3#

这里的答案缺少递归解,这里是:

defmodule M do                          
  @steps [0,1,2,3,-4,5,6,-1]

  def sum(list, acc \\ 0)
  def sum([], acc), do: acc
  def sum([h|_], acc) when not is_number(h), do: :error
  def sum([h|_], acc) when h < 0, do: acc
  def sum([h|t], acc), do: sum(t, acc + h)

  def sum_steps(), do: sum(@steps)
end

M.sum_steps()
#⇒ 6
mfpqipee

mfpqipee4#

在Erlang语法中:

1> L = [1,2,3,-4,5,6,-1].
[1,2,3,-4,5,6,-1]
2> lists:foldl(fun(X,{S,true}) when X >= 0 -> {S+X,true}; (_,{S,_}) -> {S,false} end,{0,true},L).
{6,false}

当然,即使第一个元素为负,这个函数也会解析整个列表,一个简单的“手工制作”代码可以避免这种情况:

3> SW = fun SW([H|T],S) when H >= 0 -> SW(T,S+H); SW(_,S) -> S end.
#Fun<erl_eval.36.127694169>
4> SumWhilePos = fun(P) -> SW(P,0) end.
#Fun<erl_eval.6.127694169>
5> SumWhilePos(L).
6

相关问题