我已经定义了一个(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"]
此解决方案不符合我的要求,因为我希望在不同时间添加到列表中而不是组合在一起。我怎样才能做到这一点?
答案 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的电脑,但你应该明白这一点。