Swift 将数字拆分为单个数字的数组
如果我有一个整数123,我想把数字分成一个数组[1,2,3],那么最好的方法是什么?我在这方面做了很多,我有以下工作:Swift 将数字拆分为单个数字的数组,swift,Swift,如果我有一个整数123,我想把数字分成一个数组[1,2,3],那么最好的方法是什么?我在这方面做了很多,我有以下工作: var number = 123 var digits = Array(String(number)).map{Int(strtoul((String($0)),nil,16))} 我看着它,觉得可能有更好/更简单的方法来做这件事。如果没有,那么它可能会出现在网络搜索上。有其他的想法吗?我想说,如果它没有坏,就不要修理它。我可以用另一种方式来做这件事,但它不是更短或其
var number = 123
var digits = Array(String(number)).map{Int(strtoul((String($0)),nil,16))}
我看着它,觉得可能有更好/更简单的方法来做这件事。如果没有,那么它可能会出现在网络搜索上。有其他的想法吗?我想说,如果它没有坏,就不要修理它。我可以用另一种方式来做这件事,但它不是更短或其他任何东西:
var number = 123
var digits = map(String(number)) { String($0).toInt() ?? 0 }
我对斯威夫特2的看法是:
var x = 123
var digits = String(x).characters.map { Int(String($0))! } // [1,2,3]
它更明确地描述了字符,因此我认为它非常可读。我不知道您是否是swift新手,但让我们明确一点,您使用
映射的方法最适合您想要做的事情:)
我不推荐使用另一种方法,因为对代码结构进行良好的可视化非常重要
import Foundation
var number2 = 123
var number3 : String = "\(number2)"
var array : [String] = []
var str2 = ""
for i in number3.characters
{
str2.append(i)
var string = NSString(string: "str")
string.doubleValue
array.append(str2)
str2 = ""
}
干杯使用数字字符串的UTF-8表示法更容易
因为十进制数字的UTF-8编码单元可以很容易地转换为
通过减去常数得到相应的整数:
let asciiZero = UInt8(ascii: "0")
let digits = map(String(number).utf8) { Int($0 - asciiZero) }
这也被证明是明显更快
如果性能是主要目标,那么您应该限制
该方法实现简单的整数运算,不使用字符串
或字符:
var digits : [Int] = []
while number > 0 {
digits.insert(number % 10, atIndex: 0)
number /= 10
}
以下是我的完整测试代码,以方便您使用(已编译
在MacBookPro上,Xcode 6.4处于发布模式)
Swift 3的更新:
func digits(_ number: Int) -> [Int] {
var number = number
var digits: [Int] = []
while number > 0 {
digits.insert(number % 10, at: 0)
number /= 10
}
return digits
}
print(digits(12345678)) // [1, 2, 3, 4, 5, 6, 7, 8]
这也被证明比附加数字稍微快一些
另一个Swift 3替代方案是利用全局
Swift 3.1
let number = 123456
let array = Array(sequence(state: number,
next: { return $0 > 0 ? ($0 % 10, $0 = $0/10).0 : nil }
).reversed())
print(array) // [1, 2, 3, 4, 5, 6]
Swift 3.0
let number = 123456
let array = Array(sequence(state: number,
next: { (num: inout Int) -> Int? in
return num > 0 ? (num % 10, num /= 10).0 : nil
}).reversed())
print(array) // [1, 2, 3, 4, 5, 6]
上面的方法假设一个非负数,并且将返回一个空数组([]
)is casenumber
is0
。涵盖自然数的全部范围,如下所示:
// -123 -> [1, 2, 3]
// 0 -> [0]
// 123 -> [1, 2, 3]
我们可以将上述内容修改为:
// for some number ...
let number = ...
// Swift 3.1
let array: [Int]
if number == 0 { array = [0] }
else {
array = Array(sequence(state: abs(number),
next: { return $0 > 0 ? ($0 % 10, $0 = $0/10).0 : nil }
).reversed())
}
// Swift 3.0
let array: [Int]
if number == 0 { array = [0] }
else {
array = Array(sequence(state: number,
next: { (num: inout Int) -> Int? in
return num > 0 ? (num % 10, num /= 10).0 : nil
}).reversed())
}
有关上述元组返回的一些详细信息
在上面的单行返回中,我们使用了整洁的“()
-return操作作为()
类型的元组成员内联”,我第一次看到@MartinR在他的更新改进建议中使用了这个方法。我们使用(Int,())
元组的最后一个成员来变异状态
属性num
;元组的第一个成员将在执行“计算”第二个元组成员中的()
-return操作之前进行计算
我们可以将此元组方法与使用单个defer
和return
语句执行闭包的方法进行类比。即返回语句:
return num > 0 ? (num % 10, num /= 10).0 : nil
也可以通过执行这样的闭包来实现(在本文中为“长形式”)
我还没有对这两种方法进行基准测试,但我感觉在上面的sequence(state:next:)
上下文中重复调用前者时,前者会更快
Swift 3.0 vs 3.1:在上面的下一个
结尾中的匿名参数
由于中报告的现已关闭(Swift 3.1及以后版本)错误(iOut参数需要Swift 3中的关闭签名),Swift对关闭的iOut
参数的类型推断存在限制。有关详细信息,请参见以下问答:
这就是为什么我们必须在上述Swift 3.0解决方案的next
闭包中明确注释状态的类型,而我们可以在next
闭包中为Swift 3.1解决方案使用匿名参数。在哪方面更好?更短,更快,…?我经常使用地图,这适用于我尝试过的所有数字。我想知道还有其他方法可以解决这个问题。我刚刚意识到我的问题与一个单一的答案并不匹配。但是,当我浏览其他问题的答案时,我并不总是赞同公认的答案。我喜欢其他的想法!与swift合作了一段时间,但每次发布新版本时,我有时都会问自己知道多少。。。我经常使用地图。在for循环中,“i”将默认为Character类型。map和join是swift的两个很棒的函数,因为您实际上避免了执行for循环等操作的所有麻烦。这是保持代码干净、代码更快、更智能的好方法。我建议你看看闭包。我认为这是斯威夫特最好的作品之一。真的简化了Sagreed->映射连接闭包!天哪!是的,我没有注意到“斯威夫特2”的事。。。还是回到6.4操场上。我当然喜欢它的阅读方式,一旦我们转到7,我会尝试它!你可能是对的,但这读起来有点好!在6.4操场上运行良好。仅仅因为某些东西(尚未)损坏并不是不修复它的理由。代码优化(美学或可读性事件)总是有序的。使用UTF-8代码单元似乎会带来速度优势。而且它读起来很好@pn1dude:我添加了另一个可能的解决方案(更快但更多的代码)。很好地使用了模数10和/=作为十进制移位器popper!为绝对积极的人工作Ints@ielyamani:是的。没有指定整数是零还是负,或者在这种情况下预期的结果是什么。任何需要它的人在处理这些案件时都应该没有问题。嘿,我刚想补充一个解决方案:)@MartinR啊,我希望我没有像你更新你的一样发布它!太糟糕了,我们不能在next
闭包中使用匿名参数(我想是因为inout
参数错误),或者它可能更整洁:)基于序列的解决方案比插入或附加到数组的显式循环快一点。稍后我会添加一些基准。@ MartinR,我没想到它会与显式循环保持一致,这很好。谢谢<代码>扩展二进制整数{var digits:[Self]{var sou
return num > 0 ? (num % 10, num /= 10).0 : nil
return num > 0 ? { defer { num /= 10 }; return num % 10 }() : nil