Haskell:从单个字符串中创建列表的列表

时间:2016-05-29 16:39:13

标签: string haskell functional-programming

我在txt文件中有一些数据如下所示:

  [Just 3, Nothing, Just 1, Nothing] [Nothing, Nothing, Nothing, Nothing] [Nothing, Nothing, Just 4, Nothing] [Nothing, Just 3, Nothing, Nothing]

我需要的是将包含上述值的列表列表作为整数,例如

[[3,0,1,0],[0,0,0,0],....]

等等。你知道如何正确地做到这一点吗?我可以替换什么"由0和#34;只是"部分但它将保持为单个字符串。

2 个答案:

答案 0 :(得分:1)

执行此操作的正确方法可能是使用像Text.Parsec这样的解析器库。话虽这么说,这是一个快速和黑客的方式来做到这一点,不像python程序员可能想出的那样。我们的想法是将输入字符串按到read将为我们解析的表单中。

{-# LANGUAGE OverloadedStrings #-}

import Prelude hiding (null)
import Data.Text (snoc, pack, unpack, splitOn, strip, null)
import Data.Maybe (fromMaybe)
import System.IO

parse :: String -> [[Maybe Int]]
parse = map read . map unpack . map (flip snoc ']') . filter (not . null) . map strip . splitOn "]" . pack

main :: IO ()
main = do
  input <- readFile "myfile.txt"  -- input = "[Just 3, Nothing, Just 1, Nothing] [Nothing, Nothing, Nothing, Nothing] [Nothing, Nothing, Just 4, Nothing] [Nothing, Just 3, Nothing, Nothing]"
  putStrLn . show $ map (map (fromMaybe 0)) (parse input)

parse方法的工作原理如下:

  • packString值转换为Text
  • splitOn "]"完全符合您的想法
  • map strip删除了前导和尾随空格
  • filter (not . null)删除空字符串(最后有一个字符串)
  • map (flip snoc ']')追加&#34;]&#34;字符回到每个字符串的末尾
  • map unpack将每个Text值转换回String
  • map read将每个String值解析为[Maybe Int]

答案 1 :(得分:0)

只是使用read的替代版本:

import Data.List.Split (splitOn)
import Data.Maybe      (fromMaybe)

main :: IO ()
main = do
    s <- readFile "lists.txt"
    let xs = map (\s' -> map (fromMaybe 0) (read (s' ++ "]"))) . init . splitOn "]" $ s
    print xs

这个想法很简单:首先,文件内容被读作String并绑定到s。然后,s被解析为绑定到[Int]的整数列表(xs)。为此,需要执行以下步骤:

  1. splitOn "]":拆分输入字符串s,生成字符串列表([String])。每个元素最后都会错过字符']'。此列表的最后一个元素是不受欢迎的"\n"。结果列表是:

    ["[Just 3, Nothing, Just 1, Nothing"," [Nothing, Nothing, Nothing, Nothing", ..., "\n"]
    
  2. init:删除不需要的“\ n”。

  3. map (\s' -> map (fromMaybe 0) (read (s' ++ "]"))):将每个字符串元素应用于所包含的lambda函数,其中包含:

    1. read (s' ++ "]"):将缺少的']'追加到字符串中,并将其解析为Maybe s(Num a => [Maybe a])列表。请注意,我们不需要为read明确指定类型,因为GHC可以使用fromMaybe 0来推断它(见下文)。
    2. map (fromMaybe 0):对列表的每个元素应用函数fromMaybe 0,在v时返回Just v;和0,否则。
  4. 通过这种方式,您可以使用read获取整数列表列表。

相关问题