Haskell按顺序向元组/列表添加元素

时间:2013-03-18 12:58:06

标签: list haskell

我已经定义了一个(String,Int)对的列表。

 type PatientList = [(String,Int)]

我需要以'name'和'number'的形式将数据添加到此列表中,其中number将在每个添加到列表时递增,例如,添加3个名称后的列表(或元组)将如下所示:

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

将使用以下代码捕获名称:

  do putStr "You are? "
  name <- getLine

我目前的解决方案是创建名称列表,例如(bob,ted,harry)然后使用zip,将这些列表组合如下:

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

此解决方案不符合我的要求,因为我希望在不同时间添加到列表中而不是组合在一起。我怎样才能做到这一点?

3 个答案:

答案 0 :(得分: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

答案 1 :(得分:4)

您可以使用containers包中的IntMap

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 :(得分:2)

如前所述,如果速度不是关注使用长度

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

但是如果你删除一个元素,这会弄乱你的身份,所以也许

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

我没有尝试过运行任何一个,因为我不是一台带有ghc的电脑,但你应该明白这一点。