繁体   English   中英

Haskell Int 列表:[123] 到 [1,2,3]

[英]Haskell List of Int : [123] to [1,2,3]

问题

我的 int 列表为 [123,123],我需要为 [1,2,3,1,2,3]

当前代码

我使用递归尝试了以下代码

fat::[Int]->[Int]
fat [] = []
fat (a,b,c:xs) = a : b : c : fat xs

结论

我不知道如何在列表 [123,123] 中将值分别访问为“1”、“2”、“3”

我建议在您列表的每个元素上使用此答案中给出的digs function。 它将Int拆分为数字列表( [Int] )。 然后你只需要连接结果列表。 这种“映射和连接结果”要求对于concatMap来说是一项完美的工作

fat :: [Int] -> [Int]
fat = concatMap digs

这给出了:

*Main> fat [123,123]
[1,2,3,1,2,3]

如果我理解正确的话,这就是你想要的。

splitNum :: Int -> [Int]
splitNum n | n <= 9     = [n]
           | otherwise  = (splitNum (n `div` 10)) ++ [n `mod` 10]

fat :: [Int] -> [Int]
fat x = concatMap splitNum x

splitNum 用于将 Int 转换为 [Int],方法是将其拆分为十个提醒的除法,并将生成的 Int 附加到拆分后的 rest(递归!)

现在,有一个 function 将数字转换为列表,go 通过输入,将 splitNum 应用于内部列表中的任何数字并连接所有结果列表(列表理解!)

作为一个新的 Haskell 程序员,我会给你我对这个问题的想法。 只是因为我认为有很多选择很好,尤其是来自不同经验的不同人。

这是我对这个问题的看法:

  • 对于列表中的每个项目,使用 read 将该项目转换为 char 列表。
  • 将该 char 列表发送到 function 中,该列表将该列表中的每个项目转换为一个 int,然后返回一个 int 列表。
  • 将该整数列表连接到主列表中。

澄清:

  • [123, 234]
  • 123 变成 ['1', '2', '3']
  • ['1', '2', '3'] 变成 [1, 2, 3]
  • [1, 2, 3] 在主列表中获得 concat
  • 循环重复 234 次。

util function 看起来像这样:

import Char

charsToInts :: [Char] -> [Int]
charsToInts [] = []
charsToInts (x:xs) = digitToInt x : charsToInts xs

来自势在必行的背景,这就是我解决它的方式。 可能比仅在数学上拆分数字要慢,但我认为展示一个替代方案会很有趣。

直截了当地指出问题,您不知道如何单独访问数字,因为您不了解 Haskell 类型和模式匹配。 让我试着帮助消除你的一些误解。

让我们看看你的清单:

[123, 123]

它的类型是什么? 它显然是一个整数列表,或[Int] 使用列表,您可以在构造函数:上进行模式匹配,lispers 将其称为“cons”或“列表构造函数”。 您在:的左侧放置了一个元素,在右侧放置了另一个列表。 右边的列表可以是空列表[] ,基本表示列表的结束。 Haskell 提供了“语法糖”以使列表更易于编写,但[123,456]实际上被脱糖为123:(456:[]) 因此,当您进行模式匹配(x:y:z)时,您现在可以看到x将被分配123并且y将被分配456 z将是xy之后列表的 rest ; 在这种情况下,只剩下[]

现在,与:的模式匹配适用于列表 Int不是列表,因此您不能使用:Int的数字进行模式匹配。 但是, String列表,因为String[Char]相同。 因此,如果您将Int转换为String ,则可以对每个字符进行模式匹配。

map show [123, 123]

map将 function 应用于列表的所有元素。 show可以采用Int并将其转换为String 所以我们map show Int的列表以获得String的列表。

["123", "123"]

现在让我们将这些Strings转换为Int的列表。 由于String只是[Char] ,我们将再次使用map

map digitToInt "123" -- this requires that you import Data.Char (digitToInt)

这会给我们[1,2,3] 列表中的每个Char都变成一个Int 这就是我们想要对列表["123", "123"]中的每个String执行的操作。 我们希望map digitToInt到每个字符串。 但是我们有一个String的列表。 那么我们该怎么办? 我们map吧!

map (map digitToInt) ["123", "123"]

这会给我们[[1,2,3], [1,2,3]] 几乎是我们想要的。 现在我们只需要将Int列表 ( [[Int]] ) 列表展平为Int列表 ( [Int] )。 我们怎么能做到这一点? 停止......胡歌时间! 搜索[[a]] -> [a] 我们发现第一个命中concat正是我们想要的。

让我们把它们放在一起。 首先我们做map show[Int][String] 然后我们做map (map digitToInt)[String][[Int]] 然后我们做concat[[Int]][Int] 那我们就print出来吧!

import Data.Char (digitToInt)
main = print $ concat $ map (map digitToInt) $ map show $ [123, 123]

现在让我们将大部分内容提取到 function fat

import Data.Char (digitToInt)
main = print $ fat [123, 123]
fat :: [Int] -> [Int]
fat xs = concat $ map (map digitToInt) $ map show $ xs

从这里你可以用几种不同的方式让它更漂亮。 concat $ mapconcatMap相同,并且由于我们 map 两者(map digitToInt)并按顺序show ,我们可以合并它们。 同样让它变得无意义,我们可以得到一个非常简洁的定义:

fat = concatMap (map digitToInt . show)

为了完整起见,我按照@Ancide 的建议编写了它

执行

fat' :: [Int] -> [Int]
fat' l = map (read) [[z] | z <- [x | k <- (map (show) l), x <- k]]         

说明

{- last result -}代表最后解释的代码的结果。

map (show) l

这需要l中的每个元素并将其转换为[String]

[x | k <- {- last result -}, x <- k]

k遍历最后一个结果中的所有元素时, x枚举每个k中的所有字符。 所有这些都添加到列表中。 现在您有一个String ,分别是一个[Char] ,所有数字都彼此相邻。

[[z] | z <- {- last result -}]

这部分从String中获取每个Char并将其放入一个空String中。 注意[z]部分! 这会在z周围创建一个列表,这与String相同(见上文)。 现在你有一个字符串列表,每个数字都有一个字符串。

map (read) {- last result -}

这将获取最后一个结果中的每个项目并将其转换回Int并将它们连接到[Int] 现在您有了想要结果的[Int]类型列表。

恢复

尽管这种实现是可能的,但由于所有类型转换,它既不快,也不可读。

玩弄列表单子我想出了这个。 几乎相同的@Ankur 的解决方案,除了使用列表单子:

fat :: [Int] -> [Int]
fat is = is >>= show >>= return . digitToInt

如果你有两个数字, ab ,那么你可以通过 10*a + b 将它们变成一个数字。 同样的原则适用于三个。

听起来这样做的一种方法是将Every分成三个块,然后将map a function 将三个列表变成一个数字。

这有帮助吗?

You need a function to convert Integer to string... which is obviously Show function Another function to convert a Char to Integer which is "digitToInt" in module Char

在这里我们 go:

fat::[Int]->[Int]
fat [] = []
fat ls = concat $ map (map digitToInt) (map show ls)

请让我知道它是否有效:)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM