我在Haskell中有以下列表
[
[("Name", "Alice"), ("Age", "21")],
[("Name", "Bob"), ("Age", "22")],
[("Name", "Eve"), ("Age", "20")]
]
如何获得这样的年龄列表[...]
:
[("Age", "21"), ("Age", "22"), ("Age", "20")]
我认为可以使用set comprehension来完成,但我不确定。
答案 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
!