我有一个Java属性文本文件,其中包含键值对。将这些数据加载到haskell然后访问它的一些好方法是什么?将属性文件加载到地图结构中
文件看喜欢:
XXXX=vvvvv
YYYY=uuuuu
我希望能够进入 “XXXX” 键。
我有一个Java属性文本文件,其中包含键值对。将这些数据加载到haskell然后访问它的一些好方法是什么?将属性文件加载到地图结构中
文件看喜欢:
XXXX=vvvvv
YYYY=uuuuu
我希望能够进入 “XXXX” 键。
探索一些细节ehird没有提及,而稍微不同的方法:
import qualified Data.Map as Map
type Key = String
type Val = String
main = do
-- get contents of file (contents :: String)
contents <- readFile "config.txt"
-- split into lines (optionList :: [String])
let optionList = lines contents
-- parse into map (optionMap :: Map Key Val)
let optionMap = optionMapFromList optionList
doStuffWith optionMap
optionMapFromList :: [String] -> Map.Map Key Val
optionMapFromList = foldr step Map.empty
where step line map = case parseOpt line of
Just (key, val) -> Map.insert key val map
Nothing -> map
parseOpt :: String -> Maybe (Key, Val)
parseOpt = undefined
我已经表达了我的问题的解决方案作为一个倍:取文件中的行列表,并将其变成所需的地图。折叠中的每个step
涉及检查单行,尝试将其解析为键/值对,并在成功时将其插入地图中。
我离开了parseOpt
undefined;你可以使用像ehird的parseField
或任何你喜欢的方法。也许你宁愿只分析特定的选项:
interestingOpts = ["XXXX", "YYYY"]
parseOpt line = case find (`isPrefixOf` line) interestingOpts of
Just key -> Just (key, drop 1 $ dropWhile (/= '=') line)
Nothing -> Nothing
使用前缀测试方法并不总是最好的主意,不过,如果您有(例如)选项“XX”和选项“XXXX” 。仔细观察,看看最适合您的数据的方法。如果您需要需要高性能,请使用Data.Text而不是String
s。
你可以使用像优秀Parsec(Haskell平台的一部分)的解析器库。编写一个简单的格式解析器只需要几分钟。
但是,如果真的那么简单,您可以使用split;使用标准lines
函数将字符串拆分为多行(如果需要处理空行等,则使用Data.List.Split),然后使用Data.List.Split函数将其拆分为'='
。
最简单的解决办法是滚动自己与break
:
import Control.Arrow
parse :: String -> [(String, String)]
parse = map parseField . lines
where parseField = second (drop 1) . break (== '=')
然而,这不处理的空白,空白行,或类似的东西。
至于通过键查找,一旦你有一个结构是怎样的[(String, String)]
,可以很容易地把它变成一个Map(与fromList
),并在该操作。
对于一个非常非常长的选项列表,foldr可能会打击堆栈。用foldl重写会防止这种情况发生。 – 2012-01-08 23:51:57