我目前正在学习Elixir,我仍然试图了解列表理解。我有两个列表,内容和素数的一次性列表。我使用两个列表推导,然后使用if
来确定它是否为素数,将其丢弃并从列表中删除它。
iex(25)> content = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
iex(26)> for c <- content do
...(26)> for s <- [1, 3, 5, 7] do
...(26)>
...(26)> if s == c do
...(26)> List.delete(content, s)
...(26)> end
...(26)>
...(26)> end
...(26)> end
[[[2, 3, 4, 5, 6, 7, 8, 9, 10], nil, nil, nil], [nil, nil, nil, nil],
[nil, [1, 2, 4, 5, 6, 7, 8, 9, 10], nil, nil], [nil, nil, nil, nil],
[nil, nil, [1, 2, 3, 4, 6, 7, 8, 9, 10], nil], [nil, nil, nil, nil],
[nil, nil, nil, [1, 2, 3, 4, 5, 6, 8, 9, 10]], [nil, nil, nil, nil],
[nil, nil, nil, nil], [nil, nil, nil, nil]]
但是,这会返回一个奇怪的结果 - 列表列表。我一直期待代码返回(这就是我想要的):
[2, 4, 6, 8, 9, 10]
此外,我还尝试将其与Enum.map
一起使用,但却更加混乱。有人可以建议如何获得我想要的1xN清单吗?
答案 0 :(得分:4)
for
的列表理解总是返回一个列表。因此,如果您将for
嵌套在另一个for
内,则内部for
将返回一个列表,因此外部for的每个元素都将成为一个列表 - 因此列出一个列表。没有什么奇怪的事情发生在这里。
正在发生的另一件事你可能没想到的是结果中nil
的数量:内部for
的最后一个表达式是if
而没有else
分支。这意味着如果条件为真,那么if
的主体将被返回,但如果它是假的,那么将返回nil
。
Onorio的回答(使用--/2
)对我来说很好看。您可以做的另一件事(没有列表推导)是使用Enum.reject/2
过滤非素数:
Enum.reject(content, fn n -> n in [1, 3, 5, 7] end)
如果您绝对想使用for
,可以使用警卫:
for n in contents, not n in [1, 3, 5, 7], do: n
为了完整起见,最后一件事:当你List.delete(contents, ...)
时,你不会修改原始的contents
列表。
答案 1 :(得分:2)
这是一种简单的方法:
l = [1,2,3,4,5,6,7,8,9,10]
o = [1,3,5,7,9]
d = l -- o
我不确定是否可以使用列表理解来实现您尝试实现的目标。
编辑:我应该更仔细地阅读这个问题。我认为提问者只是想通过列表理解来实现这一目的。重新阅读我可以看到的问题,我只是读错了。我编辑了我的答案。