我想求第一个负数之前所有正数的和
我在 Elixir 里找到了下面的名单。
iex(4)> steps = [0,1,2,3,-4,5,6,-1]
我计算这个列表的总和如下
Enum.reduce(steps,0,fn x,acc -> acc=acc+x end)
如果遇到负数,如何从reduce中出来?
vaj7vani1#
使用Enum.reduce_whilehttps://hexdocs.pm/elixir/Enum.html#reduce_while/3
Enum.reduce_while
[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 )
efzxgjgh2#
可以使用Enum.take_while/2https://hexdocs.pm/elixir/Enum.html#take_while/2从可枚举对象的开头获取项,而fun返回真实值。
Enum.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
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
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
4条答案
按热度按时间vaj7vani1#
使用
Enum.reduce_while
https://hexdocs.pm/elixir/Enum.html#reduce_while/3efzxgjgh2#
可以使用
Enum.take_while/2
https://hexdocs.pm/elixir/Enum.html#take_while/2从可枚举对象的开头获取项,而
fun
返回真实值。或者用速记
ipakzgxi3#
这里的答案缺少递归解,这里是:
mfpqipee4#
在Erlang语法中:
当然,即使第一个元素为负,这个函数也会解析整个列表,一个简单的“手工制作”代码可以避免这种情况: