如何将字符串转换为整数列表?

DMJ*_*DMJ 3 parsing haskell

我希望能够在一行上输入一个整数序列,例如:

97, 128, 125, 17, 2
Run Code Online (Sandbox Code Playgroud)

并让Haskell程序将输入转换为整数列表,例如:

[97, 128, 135, 17, 2]
Run Code Online (Sandbox Code Playgroud)

所以我可以做一些数学运算,比如zipWith用另一个整数列表(列表).遇到麻烦.我尝试使用read和words函数,但我无法达到预期的结果.有任何想法吗?

Mic*_*son 6

一种可能的(同样,quick'n'dirty)解决方案是使用read为列表定义的实例,它需要以下格式的字符串[item1, item2, item3...]:

convert :: String -> [Int]
convert s = read $ "[" ++ s ++ "]"
Run Code Online (Sandbox Code Playgroud)

一个更强大的解决方案是使用filter或类似解析(如另一个答案中所示)或使用解析库来正确地完成工作.

  • @CommuSoft嗯,是的,这个问题的解决方案可能不是解决其他问题的方法. (2认同)

Wil*_*sem 5

仅使用的问题words是,仍将包含逗号().

一个快速和肮脏的黑客可能是先映射所有字符,而不是数字的空间:

import Data.Char(isDigit)

cnv x | isDigit x = x
      | otherwise = ' '
Run Code Online (Sandbox Code Playgroud)

然后使用:

map read . words . map cnv :: Read b => [Char] -> [b]
Run Code Online (Sandbox Code Playgroud)

演示

*Main> ((map read . words . map cnv) "97, 128, 125, 17, 2" :: [Int]
[97,128,125,17,2]
Run Code Online (Sandbox Code Playgroud)

一个潜在的问题当然是你省略了[A-z]字符等.此外,这种方法并不是最有效的.

优点是通过使用仍然可以处理"单词"流的read所有项目read.

为什么不过滤?

人们也可以明显地使用过滤器来获得例如空格和数字.例如

map read . words . filter (\x -> isDigit x || isSpace x)
Run Code Online (Sandbox Code Playgroud)

一个潜在的问题是,数字可能不是由空格(), but only by commas (,),分号(;)等分隔.使用上面的表达式可以生成正确的结果:

(map read . words . filter (\x -> isDigit x || isSpace x)) "97, 128, 125, 17, 2" :: [Int]
[97,128,125,17,2]
Run Code Online (Sandbox Code Playgroud)

但

(map read . words . filter (\x -> isDigit x || isSpace x)) "97,128,125,17,2" :: [Int]
[97128125172]
Run Code Online (Sandbox Code Playgroud)

没有.