列表折纸〜从两个新列表的生成

时间:2015-12-23 17:03:29

标签: elixir

我目前正在学习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清单吗?

2 个答案:

答案 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

我不确定是否可以使用列表理解来实现您尝试实现的目标。

编辑:我应该更仔细地阅读这个问题。我认为提问者只是想通过列表理解来实现这一目的。重新阅读我可以看到的问题,我只是读错了。我编辑了我的答案。