拆分字符串列表并将元素提取到新列表

Split list of Strings and extrat elements to a new List

我有一个像 ["1,2,3", "4,5,6", "7,8,9"] 这样的字符串列表,我试图在 [["1","2","3"], ["4","5","6"], ["7","8","9"]] 中拆分字符串,然后我试图从一个只有新列表中的第二个元素(来自示例),如 [2,5,8],然后计算这些元素的平均值。

我最后一次尝试是这样的:

import System.IO
import Data.List

removeComa :: [String] -> [String]
removeComa [] = []
removeComa (x:xs) = splitOn "," x : removeComa xs --ERROR HERE

contentsFromCol :: [String] -> Int -> [Int]
contentsFromCol [] _ = []
contentsFromCol (x:xs) c = read x !! c ++ contentsFromCol xs c

average' :: [String] -> Int -> IO()
average' content col = do
    let contents = removeComa content
    let contents' = contentsFromCol contents col
    realToFrac (sum contents') / genericLength contents'

但我一直收到 Variable not in scope: splitOn :: [Char] -> String -> String 但我不明白为什么?

but I keep getting Variable not in scope: splitOn :: [Char] -> String -> String and i don't understand why?

因为Prelude中没有splitOn函数,实际上base包中也没有splitOn

你需要安装split包,例如用cabal install split,或者在stack项目的依赖中添加split,然后从[=18导入] =]:

import System.IO
import Data.List
import Data.List.Split(<b>splitOn</b>)

removeComa :: [String] -> [[String]]
removeComa = map (<b>splitOn</b> ",")

这也将 return 一个字符串列表列表,因此 [[String]]。在你的 contentsFromCol 中,你应该在行上使用 !! c,而不是在 read x:

的结果上
contentsFromCol :: [[String]] -> Int -> [Int]
contentsFromCol [] _ = []
contentsFromCol (x:xs) c = read (<b>x !! c</b>) : contentsFromCol xs c

您的 average' 函数没有多大意义:realToFrac … … 没有类型 IO (),因此也会引发错误。

您可以通过以下方式实现:

average' :: <b>Fractional a => [String] -> Int -> a</b>
average' content col = fromIntegral (sum contents') / genericLength contents'
    where contents' = contentsFromCol (removeComa content) col