Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Break A Number Up To An Array of Individual Digits

Tags:

swift

If I have the integer 123 and I want to break the digits into an array [1,2,3] what is the best way of doing this? I have messed around with this a lot and I have the following working:

var number = 123    
var digits = Array(String(number)).map{Int(strtoul((String($0)),nil,16))}

I look at it and feel there might be an better/easier way of doing this. If not then maybe it will come up on web searches. Any alternatives ideas?

like image 648
pn1 dude Avatar asked Sep 09 '15 18:09

pn1 dude


People also ask

How do you split a number into an array?

Typecast the integer into a string. Using the split() method to make it an array of strings. Iterate over that array using the map() method. Using the map() method returns the array of strings into an array of Integers.

How can I split an array of numbers to individual digits in Java?

You can convert a number into String and then you can use toCharArray() or split() method to separate the number into digits.

How do you break an array?

The easiest way to extract a chunk of an array, or rather, to slice it up, is the slice() method: slice(start, end) - Returns a part of the invoked array, between the start and end indices.


1 Answers

It is easier to work on the UTF-8 representation of the number string because the UTF-8 code unit of a decimal digit can easily be converted to the corresponding integer by subtracting a constant:

let asciiZero = UInt8(ascii: "0")
let digits = map(String(number).utf8) { Int($0 - asciiZero) }

This also turned out to be significantly faster.

If performance is the primary goal then you should restrict the method to simple integer arithmetic, without using strings or characters:

var digits : [Int] = []
while number > 0 {
    digits.insert(number % 10, atIndex: 0)
    number /= 10
}

Here is my complete test code for your convenience (compiled with Xcode 6.4 in Release mode on a MacBook Pro).

func digits1(number : Int) -> [Int] {
    let digits = Array(String(number)).map{Int(strtoul((String($0)), nil, 16))}
    return digits
}

func digits2(number : Int) -> [Int] {
    // Use a static property so that the constant is initialized only once.
    struct Statics {
        static let asciiZero = UInt8(ascii: "0")
    }

    let digits = map(String(number).utf8) { Int($0 - Statics.asciiZero) }
    return digits
}

func digits3(var number : Int) -> [Int] {
    var digits : [Int] = []
    while number > 0 {
        digits.insert(number % 10, atIndex: 0)
        number /= 10
    }
    return digits
}

func measure(converter: (Int)-> [Int]) {
    let start = NSDate()
    for n in 1 ... 1_000_000 {
        let digits = converter(n)
    }
    let end = NSDate()
    println(end.timeIntervalSinceDate(start))
}

measure(digits1) // 10.5 s
measure(digits2) // 1.5 s
measure(digits3) // 0.9 s

Update for 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]

This also turned out to be slightly faster than appending the digits to an array and reversing it at the end.

like image 191
Martin R Avatar answered Oct 22 '22 03:10

Martin R