2014-11-21 117 views
1

我已经在Haskell以下列表如何提取一个列表的列表元组在Haskell

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

我怎样才能得到一个列表中的时代这样的[...]

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

我认为这可以使用集合理解,但我不知道。

+0

如果你想从这个特定列表中提取元组,你已经有了答案。如果您需要使用通用列表,请说明一般要求。你不想从每个列表中提取第二个条目,或者在其中有“Age”的条目或其他内容。 – 2014-11-21 06:52:49

+0

@Franky是的,你说得对,我把'(String,Int)'改成'(String,String)' – Krimson 2014-11-21 07:00:08

+2

你在寻找比map(!! 1)更复杂的东西吗? – 2014-11-21 07:20:00

回答

3

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

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

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


如果你总是想在开始与“年龄在元组值“可以使用以下

map (lookup "Age") $ theList 

这几乎工作,但将返回一个类型[Maybe String]。您可以使用fromJust删除Just,但要小心,如果程序不存在,这会使程序崩溃。一个更清洁的方法是使用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 
0

我能想到这样做的最好的方法是这样:

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

其检索第一个列表中的每个子列表的第二个元素这仅仅是一个函数。这应该在这个特殊的情况下工作,但如果你想元组的“名称”标签相匹配,这是比较难:

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" 

这将提取嵌套数组的“时代”的元组,没有触摸Maybe

相关问题