对 Haskell 中字符串列表中的所有成员执行操作

Making an operation to all members in a list of strings in Haskell

提问人:MechWright 提问时间:7/2/2023 最后编辑:MechWright 更新时间:7/6/2023 访问量:94

问:

我想对 Haskell 字符串列表中的所有成员进行特定操作。 例如,我有一个工作时间字符串列表(从导出的 Notebook 文件中读取):

[“工作时间:9-17(8h)”, “工作时间:9-16(7h)”, “工作时间:10-17(7h)”, “工作时间:8-17:30(9.5h)”]。

我想从这里的每个元素中获取括号中的工作时间 string list 并用它们创建一个新的 Double 列表。

经过几个小时的搜索,我还没有找到任何例子 完成。整数列表或函数有很多技巧,它们需要 一个长字符串并从中列出字符串,但对工作没有什么真正有用的 带有字符串列表。

有人可以帮忙吗?

字符串 列表 哈斯克尔

评论

0赞 willeM_ Van Onsem 7/2/2023
你试过什么?什么不起作用?

答:

3赞 willeM_ Van Onsem 7/2/2023 #1

最简单的方法可能是使用正则表达式,我们可以用软件包来做到这一点,所以安装它,例如使用 cabal:rex

cabal install rex

然后我们可以用准引号为单个字符串提取它:

{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE ViewPatterns #-}

import Text.Regex.PCRE.Rex (rex)

extract :: String -> Double
extract [rex|(?{read -> x}\d+[.]?\d*)h[)]|] = x
extract _ = 0

我将字符串列表转换为使用该函数的列表。Doubleextract

2赞 MechWright 7/6/2023 #2

Willem WO:的答案可能是形式上正确的,也是适应性最强的;但是,就我而言,定义函数就足够了:

extractBetween :: Eq a => a -> a -> [a] -> [a] 
extractBetween a b = drop 1 . takeWhile (/=b) . dropWhile (/=a)

removeLetter :: Char -> [Char] -> [Char]
removeLetter a = filter (not . isSpace) . takeWhile (`notElem` [a])

和主要功能来做工作

main :: IO()
main = do
  contents <- getContents
  let workHours = ...filter relevant lines...
  let betw = extractBetween '(' ')' <$> workHours
  let hours = removeLetter 'h' <$> betw 
  let totalHours = foldl (+) 0.0 $ read <$> hours
  print "Total working hours this month:"
  print totalHours

其中内容可以从文本文件中读取,并且...过滤相关行...指 从内容中过滤带有“工作时间:(x h)”的行。