如果某个条件为true,我想使用列表推导来获得一个字符串,但如果条件不为真,则将空字符串放入(或空列表)中。
例如:[ Bob | i <- [3..6], i == 4 ]
这会给出列表["Bob"]
,但我想得到:[ "" , "Bob" , "" , "" ]
所以每当i
不等于4时都会出现空字符串。
是否可以在列表理解中执行此操作。
答案 0 :(得分:4)
使用if
构造。
[ if i == 4 then "Bob" else "" | i <- [3..6] ]
虽然没有列表理解可能会更好
map f [3..6]
where
f 4 = "Bob"
f _ = ""
答案 1 :(得分:3)
管道的左侧不一定是值。你可以这样做:[ if i == 4 then "Bob" else "" | i <- [3..6]]
。
答案 2 :(得分:3)
这不起作用的原因是因为您使用i == 4
作为过滤器:
[ "Bob" | i <- [3..6], i == 4 ]
-- ^ filter
这意味着仅在i == 4
的情况下,您才会将"Bob"
添加到列表中。如果条件为True
例如两次(例如i < 5
),那么我们会两次产生"Bob"
。
条件不是过滤器:它确定应该将哪些添加到列表中,而不是应该添加什么条件。在这种情况下,您可以使用检查条件的函数,并返回不同的结果。
我们可以使用bool :: a -> a -> Bool -> a
(这是 catamoprhism 而不是Bool
):
import Data.Bool(bool)
[ bool "" "Bob" (i == 4) | i <- [3..6] ]
请注意,我们也可以使用map
:
import Data.Bool(bool)
map (bool "" "Bob" . (4 ==)) [3..6]
答案 3 :(得分:-2)
你拥有的东西没有错。只是你必须强制结果是否符合条件或不符合条件。这样做的方法是将你拥有的东西放在列表理解中并让它“执行”很多次。
[ concat ["Bob" | x == 4] | x <- [3..6] ]
x不等于4的条件产生并且空列表'[]'因此concat
将它们转换为相同的字符串以实现列表一致性。