Do2
Do2

Reputation: 1791

How to split an Int to its individual digits?

I am trying to split an Int into its individual digits, e.g. 3489 to 3 4 8 9, and then I want to put the digits in an Int array.

I have already tried putting the number into a string and then iterating over each digit, but it doesn't work:

var number = "123456"

var array = [Int]()

for digit in number {
    array.append(digit)
}

Any ideas?

Upvotes: 45

Views: 58883

Answers (11)

Cesar Trujillo
Cesar Trujillo

Reputation: 11

You can use:

let number = -123
let regex = /-?\d/
let values = String(number).matches(of: regex).compactMap { Int($0.output) }
print(values) // [-1, 2, 3]

This code takes into account negative values

Upvotes: 1

Zihan
Zihan

Reputation: 952

There is a simpler method to achieve this. Say x = 12345 , then

var s = String(x);
var numArray = Array(s);

clean, easy-to-read code.

Upvotes: 1

Etozhekolyan
Etozhekolyan

Reputation: 41

if you need convert integer to Array

let num = 12345
let array = String(num).compactMap({$0.wholeNumberValue})
print("\(array), \(type(of: array))")
//[1,2,3,4,5], Array<Int>

Upvotes: 4

oscarr
oscarr

Reputation: 529

Swift 5

extension Int {
    func digits() -> [Int] {
        var digits: [Int] = []
        var num = self
        
        digits.append(num % 10)
        
        while num >= 10  {
            num = num / 10
            digits.append(num % 10)
        }
        
        return digits.reversed()
    }
}

Upvotes: 7

Leo Dabus
Leo Dabus

Reputation: 236420

We can also extend the StringProtocol and create a computed property:

edit/update: Xcode 11.5 • Swift 5.2

extension StringProtocol  {
    var digits: [Int] { compactMap(\.wholeNumberValue) }
}

let string = "123456"
let digits = string.digits // [1, 2, 3, 4, 5, 6]

extension LosslessStringConvertible {
    var string: String { .init(self) }
}

extension Numeric where Self: LosslessStringConvertible {
    var digits: [Int] { string.digits }
}

let integer = 123
let integerDigits = integer.digits // [1, 2, 3]

let double = 12.34
let doubleDigits = double.digits   // // [1, 2, 3, 4]

In Swift 5 now we can use the new Character property wholeNumberValue

let string = "123456"

let digits = string.compactMap{ $0.wholeNumberValue } // [1, 2, 3, 4, 5, 6]

Upvotes: 109

Ralf Ebert
Ralf Ebert

Reputation: 4092

extension Int {
    var digits : [Int] {
        var result = [Int]()
        var remaining = abs(self)
        while remaining > 0 {
            result.insert(remaining % 10, at: 0)
            remaining /= 10
        }
        return result
    }
}

Upvotes: 1

Abhijit
Abhijit

Reputation: 392

You can use this

extension Int {

func numberOfDigits() -> Int {
    if abs(self) < 10 {
        return 1
    } else {
        return 1 + (self/10).numberOfDigits()
    }
}

func getDigits() -> [Int] {
    let num = self.numberOfDigits()
    var tempNumber = self
    var digitList = [Int]()

    for i in (0..<num).reversed() {
        let divider = Int(pow(CGFloat(10), CGFloat(i)))
        let digit = tempNumber/divider
        digitList.append(digit)
        tempNumber -= digit*divider
    }
    return digitList
}

}

Upvotes: 3

Israel Manzo
Israel Manzo

Reputation: 237

You can use this:

// input -> "123456"
// output -> [1, 2, 3, 4, 5, 6]
// Get the string, convert it in an Array(), 
// use a loop (convert i in Int()), to add it into a container, then return it. Done! 

    func getDigitsFromString(for string: String) -> [Int]{
        let stringInt = Array(string)
        var array = [Int]()
        for i in stringInt {
            if let i = Int(String(i)) {
                array.append(i)
            }
        }
        return array
    }

Upvotes: 0

Tiago Couto
Tiago Couto

Reputation: 351

A solution without having to convert the int to string....

Example

1234%10 = 4 <-
1234/10 = 123
123%10 = 3 <-
123/10 = 12
12%10 = 2 <- 
12/10 = 1
1%10 = 1 <-

var num = 12345
var arrayInt = [Int]()
arrayInt.append(num%10)
while num >= 10 {
  num = num/10
  arrayInt.insert(num%10, at: 0)
}

Upvotes: 8

Zohra Khan
Zohra Khan

Reputation: 5302

You can try this:

var number = "123456"
var array = number.utf8.map{Int($0)-48}

You can make use of the utf8 property of String to directly access the ASCII value of the characters in the String representation of your number.

Upvotes: 4

yshilov
yshilov

Reputation: 794

this code works:

var number = "123456"
var array = number.utf8.map{Int(($0 as UInt8)) - 48}

this might be slower:

var array = number.characters.map{Int(String($0))!}

and if your number is less or equal than Int.max which is 9223372036854775807 here is the fastest variant (and if your number>Int.max you can split your long string that represents your number into 18-digit groups to make this variant work on large strings)

var array2 = [Int]()
var i = Int(number)!
while i > 0 {array2.append(i%10); i/=10}
array2 = array2.reverse()

Upvotes: 3

Related Questions