鉴于Alice的三元组和Bob的三元组(列表),我需要比较每个元素,以便alice_triplet[i]
> bob_triplet[i]
,爱丽丝的得分加1,反之亦然。
我有这段代码:
def main do
alice_triplet = [5, 6, 7]
bob_triplet = [3, 6, 10]
alice_score = 0
bob_score = 0
Enum.zip(alice_triplet, bob_triplet)
|> Enum.each(fn
tuple when elem(tuple, 0) > elem(tuple, 1) -> alice_score = alice_score + 1
tuple when elem(tuple, 1) > elem(tuple, 0) -> bob_score = bob_score + 1
_ -> nil end)
IO.puts alice_score
IO.puts bob_score
end
但是,输出是:
0
0
为什么呢?我认为这是关于可变范围的,因为我收到了这个警告:
警告:变量" alice_score"未使用的解决方案.ex:12
警告:变量" bob_score"未使用的解决方案.ex:13
是否有更多功能性"这样做的方法?我正在学习Elixir(实际上是FP),所以任何建议都会受到赞赏。
答案 0 :(得分:2)
语句alice_score = alice_score + 1
不会修改外部alice_score
,它会创建一个新的本地alice_score
,其值设置为外部值+ 1.这已在{{3 }} many。解决方案几乎总是将Enum.reduce/3
与您需要更改的状态一起用作累加器。
以下是如何将其应用于您的代码:
alice_triplet = [5, 6, 7]
bob_triplet = [3, 6, 10]
{alice_score, bob_score} = Enum.zip(alice_triplet, bob_triplet) |>
Enum.reduce({0, 0}, fn
tuple, {as, bs} when elem(tuple, 0) > elem(tuple, 1) -> {as + 1, bs}
tuple, {as, bs} when elem(tuple, 1) > elem(tuple, 0) -> {as, bs + 1}
_, {as, bs} -> {as, bs}
end)
IO.puts alice_score
IO.puts bob_score
您还可以使用模式匹配而不是elem/2
来简化代码(elem/2
很少用于惯用的Elixir代码中):
alice_triplet = [5, 6, 7]
bob_triplet = [3, 6, 10]
{alice_score, bob_score} = Enum.zip(alice_triplet, bob_triplet) |>
Enum.reduce({0, 0}, fn
{a, b}, {as, bs} when a > b -> {as + 1, bs}
{a, b}, {as, bs} when b > a -> {as, bs + 1}
_, {as, bs} -> {as, bs}
end)
IO.puts alice_score
IO.puts bob_score
两种情况下的输出都是
1
1