过滤列表列表

时间:2013-09-24 10:39:06

标签: list haskell filter

我想知道如何从列表列表中过滤整个列表

Example: [ ["Bob", "Baker", "male", "70000"],
         ["Alice", "Allen", "female", "82000"] ] 

现在我想过滤包含女性的列表。所以输出将是:

["Alice", "Allen", "female", "82000"]

由于

2 个答案:

答案 0 :(得分:8)

Prelude> let a = [ ["Bob", "Baker", "male", "70000"], ["Alice", "Allen", "female", "82000"] ]
Prelude> filter (elem "female") a
[["Alice","Allen","female","82000"]]

答案 1 :(得分:8)

Ankur的答案肯定会解决你的问题,但我想提出一个可以让你的生活更轻松的建议。您似乎将所有数据存储为列表中的字符串,但您真正想要的是一种数据类型,它可以以更有条理的方式保存所有这些数据,这可以使用Haskell数据类型完成,例如:

data Person = Person {
    firstName :: String,
    lastName :: String,
    gender :: String,
    salary :: String
    } deriving (Eq, Show)

然后,您可以使用filter (("female" ==) . gender) a轻松对数据进行排序。虽然这是前面的代码更多,如果你要为“Mr”,“Mrs”等添加“title”字段,那么如果你在第一个字段或者第一个字段添加它并不重要最后一个字段,这段代码仍然有效。此外,如果由于某种原因你有一个像["Bob", "Baker", "male", "70000", "female"]这样的无效值,Ankur的解决方案会给你一个不正确的结果,但是使用自定义数据类型,这甚至都不会编译。

您可以通过一些调整来进一步改善数据结构。我建议为性别制作数据类型,然后使用IntDouble作为工资字段,这样你就可以了

data Gender = Male | Female deriving (Eq, Show, Read)

data Person = Person {
    firstName :: String,
    lastName :: String,
    gender :: Gender,
    salary :: Int
    } deriving (Eq, Show)

filtGender :: Gender -> [Person] -> [Person]
filtGender gend people = filter ((gend ==) . gender) people

main :: IO ()
main = do
    let people = [Person "Bob" "Baker" Male 70000,
                  Person "Alice" "Allen" Female 82000]
    putStr "The females are: "
    print $ filtGender Female people
    putStr "The males are: "
    print $ filtGender Male people