2014-11-21 39 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

相關問題