2013-03-18 106 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的計算機,但你應該明白。