2013-03-18 120 views
0

我已经定义的(字符串,整数)对的列表。Haskell的添加元素到元组/列表,以便

type PatientList = [(String,Int)] 

我需要后,3个增加将数据添加到这个列表的形式“名”和“数量”,其中数量将因每个除了列表中增加,例如列表(或元组)会看像:

[("bob", 1), ("ted", 2), ("harry", 3)] 

名称将使用下面的代码被捕获:

do putStr "You are? " 
    name <- getLine 

我目前的解决方案是创建名称如清单(BOB,泰德,哈利),然后用ZIP,如下组合这些列表:

zip = [1...]["bob","ted","harry"] 

该解决方案不能满足我的要求,我想在不同的时间添加到列表中,而不是结合在了一起。我怎样才能做到这一点?

+1

如果效率ISN如果您不关心(或者列表不多),您可以使用“长度患者”来了解接下来的数字。如果需要考虑效率,请使用不同的数据结构来存储大小并且更快地追加/更新。 – 2013-03-18 13:01:46

+2

是否有一个很好的理由,包括在列表中的号码?看起来你可以在需要的时候用'[1 ..]'来压缩它们。 – 2013-03-18 13:03:54

+0

例如,如果我从列表中删除的元素,即数不能被再次上再压缩和解使用。 – ZeeeeeV 2013-03-18 13:13:48

回答

5

是不是更好地保持在相反的顺序列表?

[("harry", 3), ("ted", 2), ("bob", 1)] 

比增加会在一定的时间:

add :: PatientList -> String -> PatientList 
add [] newName = [newName] 
add ((oldName, x):xs) newName = (newName, x+1):(oldName, x):xs 

当你需要为了整个列表,你只是在O(lenght yourList)线性时间:

reverse patientList 
4

你可以使用一个IntMap,从containers包。

import Data.IntMap (IntMap) 
import qualified Data.IntMap as IntMap 

type PatientList = IntMap String 

registerPatient :: PatientList -> String -> PatientList 
registerPatient pList name 
    | IntMap.null plist = IntMap.singleton 1 name 
    | otherwise   = let (n, _) = findMax pList 
         in IntMap.insert (succ n) name plist 
2

至于说,如果速度不是问题使用长度

add :: String -> [(String, Int)] -> [(String, Int)] 
add name xs = xs ++ [(name, length xs)] 

之前但是,如果你删除一个元素这会搞乱你的ID,这样也许

add name xs = xs ++ [(name, 1 + (snd (last xs)))] 

我的天堂” t试着运行这些,因为我不是一台使用ghc的计算机,但你应该明白。