如何从Haskell中的列表列表中提取元组

时间:2014-11-21 06:44:46

标签: haskell

我在Haskell中有以下列表

[
    [("Name", "Alice"), ("Age", "21")],
    [("Name", "Bob"), ("Age", "22")],
    [("Name", "Eve"), ("Age", "20")]
]

如何获得这样的年龄列表[...]

[("Age", "21"), ("Age", "22"), ("Age", "20")]

我认为可以使用set comprehension来完成,但我不确定。

2 个答案:

答案 0 :(得分:3)

好吧,我会给你一个答案,但首先请注意,你提供给我们的列表类型是不允许的......

每个列表中的第一个类型为(String, String),第二个类型为Num a=>(String, a)。 Haskell不允许混合列表。

话虽这么说,一旦你解决了这个问题(例如,将年龄元组改为("age", "2")),你有几个选择:


如果您始终希望以“Age”开头的元组中的值可以使用以下

map (lookup "Age") $ theList

这几乎可以,但会返回[Maybe String]类型。您可以使用Just删除fromJust,但要小心,如果程序不存在,这将导致程序崩溃。更简洁的方法是使用fromMaybe,这样可以在Nothing的情况下填写默认值。

map (fromMaybe "ageless" . lookup "Age") $ theList

如果您始终想要列表中的第二个值,请使用

map (snd . tail) $ theList

同样,如果任何列表没有两个项目,程序将崩溃。

“安全”包中有tail的安全版本(https://hackage.haskell.org/package/safe-0.3.3/docs/Safe.html)。例如,您可以使用

map (snd . tailDef ("", "Ageless")) $ theList

答案 1 :(得分:0)

我能想到的最好的方式就是这样:

getAges :: [[a]] -> [a]
getAges = map (!! 1)

这只是一个检索第一个列表中每个子列表的第二个元素的函数。这应该适用于这种特殊情况,但是如果你想将元组与“Name”标签相匹配,那就更难了:

getAges :: [[a]] -> [a]
getAges list = do
        person <- list
        tags <- person
        get' tags
    where get' (tag,val) | tag == "Age" = return (tag,val)
                         | otherwise    = fail "Not age tag"

这将从嵌套数组中提取“Age”元组,而不需要Maybe