我有一个看起来像这样的文本文件:
ccc 1 1
bbb 2 2
aaa 3 3
我想创建一个函数,通过第一个单词获取整行:
f bbb = "bbb 2 2"
f aaa = "aaa 3 3"
我编写了以下代码:
contents !! (fromJust (findIndex (name `isInfixOf`) contents))
哪里contents
是包含上述文本的字符串列表。读取文件并使用这些函数后:
all <- readFile file
contents <- lines all
它有效,但看起来不太好。
有没有更直接的方法来实现功能f
(从上面)?
我想也许Data.List.find
或Data.Text.find
可以提供帮助,但它们似乎不匹配。
为什么不在前缀上过滤行?
Prelude> contents = lines "ccc 1 1\nbbb 2 2\naaa 3 3"
Prelude> import Data.List
Prelude Data.List> f prefix = head $ filter (isInfixOf prefix) contents
Prelude Data.List> f "aaa"
"aaa 3 3"
Prelude Data.List> f "abc"
"*** Exception: Prelude.head: empty list
head
如果您想要所有匹配的行(可能是一个空列表),您可以删除。
如果你想多次使用 f ,地图会有更好的表现,但前提是你在给定行的第一个单词(而不是任何前缀)的情况下查找一行:
Prelude> contents = lines "ccc 1 1\nbbb 2 2\naaa 3 3"
Prelude> import Data.Map (fromList, (!))
Prelude Data.Map> m = fromList $ zip =<< (map $ head.words) $ contents
Prelude Data.Map> m!"aaa"
"aaa 3 3"
Prelude Data.Map> m!"abc"
"*** Exception: Map.!: given key is not an element in the map
CallStack (from HasCallStack):
error, called at libraries/containers/Data/Map/Base.hs:489:16 in containers-0.5.7.1:Data.Map.Base
运算符(!)
将在列表版本中找到O(log n)与O(n)中的值。
一些解释:
fromList
创建一个给定列表的地图 (key, value)
map $ head.words
取列表中每个元素的第一个单词(zip =<< g) contents
相当于zip (g contents) contents
(这里:用线条压缩第一个单词)本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句