给定一个任意数字,我如何单独处理数字的每个数字?
修改
我添加了Foo
可能会做的事情的基本示例。
例如,在C#中,我可能会这样做:
static void Main(string[] args)
{
int number = 1234567890;
string numberAsString = number.ToString();
foreach(char x in numberAsString)
{
string y = x.ToString();
int z = int.Parse(y);
Foo(z);
}
}
void Foo(int n)
{
Console.WriteLine(n*n);
}
答案 0 :(得分:78)
您听说过div and mod吗?
如果您想先处理最重要的数字,您可能想要反转数字列表。将数字转换为字符串是一种受损的做事方式。
135 `div` 10 = 13
135 `mod` 10 = 5
概括成一个函数:
digs :: Integral x => x -> [x]
digs 0 = []
digs x = digs (x `div` 10) ++ [x `mod` 10]
或反过来:
digs :: Integral x => x -> [x]
digs 0 = []
digs x = x `mod` 10 : digs (x `div` 10)
这会将0
视为没有数字。如果你愿意,一个简单的包装函数可以处理这种特殊情况。
请注意,此解决方案不适用于负数(输入x
必须是整数,即整数)。
答案 1 :(得分:19)
digits :: Integer -> [Int]
digits = map (read . (:[])) . show
或者您可以将其返回[]
:
digits :: Integer -> [Int]
digits = map (read . return) . show
或者,使用Data.Char.digitToInt:
digits :: Integer -> [Int]
digits = map digitToInt . show
和丹尼尔一样,但是点免费使用Int,因为数字不应该超过maxBound :: Int
。
答案 2 :(得分:13)
你也可以从Hackage中重用digits
。
答案 3 :(得分:12)
使用帖子中使用的相同技巧,您可以:
digits :: Integer -> [Int]
digits n = map (\x -> read [x] :: Int) (show n)
看到它的实际效果:
Prelude> digits 123
[1,2,3]
这有帮助吗?
答案 4 :(得分:10)
教科书展开
import qualified Data.List as L
digits = reverse . L.unfoldr (\x -> if x == 0 then Nothing else Just (mod x 10, div x 10))
答案 5 :(得分:9)
您可以使用
digits = map (`mod` 10) . reverse . takeWhile (> 0) . iterate (`div` 10)
或反向订单
rev_digits = map (`mod` 10) . takeWhile (> 0) . iterate (`div` 10)
迭代部分生成一个无限列表,将每个步骤中的参数除以10,因此12345变为[12345,1234,123,12,1,0,0 ..]。 takeWhile部分仅采用列表中有趣的非null部分。然后我们反转(如果我们想)并取每个数字列表的最后一位数。
我在这里使用了无点样式,因此您可以想象“等式”两侧的无形参数n。但是,如果您想以这种方式编写,则必须用.
替换顶级$
:
digits n = map(`mod` 10) $ reverse $ takeWhile (> 0) $ iterate (`div`10) n
答案 6 :(得分:2)
通过列表理解:
import Data.Char
digits :: Integer -> [Integer]
digits n = [toInteger (digitToInt x) | x <- show n]
输出:
> digits 1234567890
[1,2,3,4,5,6,7,8,9,0]
答案 7 :(得分:2)
Applicative。 Pointfree。 Origami。整齐。
享受:
import Data.List
import Data.Tuple
import Data.Bool
import Control.Applicative
digits = unfoldr $ liftA2 (bool Nothing) (Just . swap . (`divMod` 10)) (> 0)
答案 8 :(得分:2)
以上是对上述答案的改进。这避免了开头的额外0(例如:[0,1,0]为10,[0,1]为1)。使用模式匹配来处理x <1的情况。 10不同:
toDigits :: Integer -> [Integer] -- 12 -> [1,2], 0 -> [0], 10 -> [1,0]
toDigits x
| x < 10 = [x]
| otherwise = toDigits (div x 10) ++ [mod x 10]
我会回答这个问题,但我没有所需的声誉点:(
答案 9 :(得分:1)
接受的答案很好但是在负数的情况下失败,因为TypeError Traceback (most recent call last)
<ipython-input-81-e74a15accb5b> in <module>()
5 print 'The first 5 tweets for \"{}\":\n'.format(keywords[0])
6 for txt in k1_tweets_processed[0:5]:
----> 7 print txt['text']
8 print
9
TypeError: list indices must be integers, not str
评估为9.如果你希望这个正确地处理负数...可能不是这种情况下面的代码将允许它
mod (-1) 10
答案 10 :(得分:1)
返回[Integer]列表
import Data.Char
toDigits :: Integer -> [Integer]
toDigits n = map (\x -> toInteger (digitToInt x)) (show n)
答案 11 :(得分:1)
我懒于编写我的自定义函数,所以我用它搜索了一下,令我感到惊讶的是,该网站上的答案都没有提供真正好的解决方案-高性能和类型安全。所以就在这里,也许有人想使用它。基本上:
[]
吗?)-XStrict
关联,允许Haskell进行严格性分析并优化内部循环。享受:
{-# LANGUAGE Strict #-}
digits :: Integral a => a -> NonEmpty Word8
digits = go [] where
go s x = loop (head :| s) tail where
head = fromIntegral (x `mod` 10)
tail = x `div` 10
loop s@(r :| rs) = \case
0 -> s
x -> go (r : rs) x
答案 12 :(得分:1)
我一直在遵循以下步骤(基于this comment):
toDigits :: Integer -> [Integer]
toDigits a = [(read([m])::Integer) | m<-show(a)]
main = print(toDigits(1234))
答案 13 :(得分:0)
接受的答案是正确的,只是当输入为0时它将输出一个空列表,但我相信输入为零时输出应为[0]
。
当输入为负时,我不认为它处理的情况。下面是我的实现,它解决了上述两个问题。
toDigits :: Integer -> [Integer]
toDigits n
| n >=0 && n < 10 = [n]
| n >= 10 = toDigits (n`div`10) ++ [n`mod`10]
| otherwise = error "make sure your input is greater than 0"
答案 14 :(得分:0)
我想在此页面上完善Dave Clarke的答案。归结为在数字上使用div
和mod
并将其结果添加到列表中,只是这一次它不会出现反转,也不会求助于++
(连接速度较慢) )。
toDigits :: Integer -> [Integer]
toDigits n
| n <= 0 = []
| otherwise = numToDigits (n `mod` 10) (n `div` 10) []
where
numToDigits a 0 l = (a:l)
numToDigits a b l = numToDigits (b `mod` 10) (b `div` 10) (a:l)
该程序是UPenn CIS 194课程中一个问题的解决方案,可以在here上使用。您将数字相除,以整数形式查找结果,其余部分以另一个形式查找。您将它们传递给第三个参数为空列表的函数。如果除法的结果为0,则其余部分将添加到列表中。如果它是另一个数字,则将再次调用该函数。其余的将按顺序添加到最后。
注意:这是用于数字的,这意味着左边的零不会计数,这将允许您使用其数字进行进一步的操作。
答案 15 :(得分:-1)
我试图继续使用尾递归
toDigits :: Integer -> [Integer]
toDigits x = reverse $ toDigitsRev x
toDigitsRev :: Integer -> [Integer]
toDigitsRev x
| x <= 0 = []
| otherwise = x `rem` 10 : toDigitsRev (x `quot` 10)
答案 16 :(得分:-2)
digits = reverse . unfoldr go
where go = uncurry (*>) . (&&&) (guard . (>0)) (Just . swap . (`quotRem` 10))