Get Integer Value from String in Swift

Get integer value from string in swift

Swift 2.0 you can initialize Integer using constructor

var stringNumber = "1234"
var numberFromString = Int(stringNumber)

Swift How to get integer from string and convert it into integer

First, we split the string so we can process the single items. Then we use NSCharacterSet to select the numbers only.

import Foundation

let str = "I have to buy 3 apples, 7 bananas, 10eggs"
let strArr = str.split(separator: " ")

for item in strArr {
let part = item.components(separatedBy: CharacterSet.decimalDigits.inverted).joined()

if let intVal = Int(part) {
print("this is a number -> \(intVal)")
}
}

Swift 4:

let string = "I have to buy 3 apples, 7 bananas, 10eggs"
let stringArray = string.components(separatedBy: CharacterSet.decimalDigits.inverted)
for item in stringArray {
if let number = Int(item) {
print("number: \(number)")
}
}

Converting String to Int with Swift

Basic Idea, note that this only works in Swift 1.x (check out ParaSara's answer to see how it works in Swift 2.x):

    // toInt returns optional that's why we used a:Int?
let a:Int? = firstText.text.toInt() // firstText is UITextField
let b:Int? = secondText.text.toInt() // secondText is UITextField

// check a and b before unwrapping using !
if a && b {
var ans = a! + b!
answerLabel.text = "Answer is \(ans)" // answerLabel ie UILabel
} else {
answerLabel.text = "Input values are not numeric"
}

Update for Swift 4

...
let a:Int? = Int(firstText.text) // firstText is UITextField
let b:Int? = Int(secondText.text) // secondText is UITextField
...

How to convert a String to an Int in Swift?

Use the prefix function on the characters array

let startString = "20932121133222"
let prefix = String(startString.characters.prefix(2))
let num = Int(prefix)

Prefix allows you to get the first n elements from the start of an array, so you get these, convert them back to a String and then convert the resulting String to an Int

How to parse a String like 14px to get Int value 14 in Swift

If string always come with just px at last you can subscript it and ignore the last 2 characters.

let str = "14px"  
var numStr = str.substring(to: str.index(name.endIndex, offsetBy: -2))
print(numStr) // "14"
//Now you can convert "14" to Int
print(Int(numStr))

Or

print(Int(String(str.characters.dropLast(2))))

How to convert 'String.Element' to 'Int'?

What's the issue in sum += i, as the error said, i is a Character, and sum a Int.

Can you make addition between bananas & apples? It's the same logic here.

So you might want to have its Int equivalent with Int(i)

It's returning an optional value, because there is no guarantee that i is valid. You check isNumber before hand, but the line itself doesn't know that. So you can soft unwrap, or if you are sure force unwrap:

sum += Int(String(i))! //Char -> String -> Int

Because there is a String.init(someChar), and Int.init(someString), but not Int.init(someChar), that's why there is the double init().

BUT, keeping your logic, you are iterating characters per characters...
So, in the end you have:

1 + 2 + 3 + 0 + 6 + 7 (ie 19), not 1 + 2 + 30 + 67 (ie 100) as expected.

So if you want to iterate, you need to "group" the consecutive numbers...

With basic for loops, your can do this (it's a possible solution, might no be the better one, but a working one)

let numsInStr = "1abc2x30yz67"

var lastWasNumber = false
var intStrings: [String] = []

for aCharacter in numsInStr {
if aCharacter.isNumber {
if !lastWasNumber {
intStrings.append(String(aCharacter))
} else {
intStrings[intStrings.count - 1] = intStrings[intStrings.count - 1] + String(aCharacter)
}
lastWasNumber = true
} else {
lastWasNumber = false
}
print("After processing: \(aCharacter) - got: \(intStrings)")
}

print(intStrings)

var sum = 0
for anIntString in intStrings {
sum += Int(anIntString)!
}
print("Sum: \(sum)")

At your level, never hesitate to add print() (but never just the variable, always add an additional text which will be context to know from where it's called).

The output being:

$>After processing: 1 - got: ["1"]
$>After processing: a - got: ["1"]
$>After processing: b - got: ["1"]
$>After processing: c - got: ["1"]
$>After processing: 2 - got: ["1", "2"]
$>After processing: x - got: ["1", "2"]
$>After processing: 3 - got: ["1", "2", "3"]
$>After processing: 0 - got: ["1", "2", "30"]
$>After processing: y - got: ["1", "2", "30"]
$>After processing: z - got: ["1", "2", "30"]
$>After processing: 6 - got: ["1", "2", "30", "6"]
$>After processing: 7 - got: ["1", "2", "30", "67"]
$>["1", "2", "30", "67"]
$>100

We rely on Int(someString) (and force unwrapping), but sum += Int(anIntString) ?? 0 should be safer. Since for too big values, if you have "a1234567890123456789123456789123456789" for instance, I'm not sure that Int will be big enough to handle that value. That some edges cases that you need to be aware of.

With high level methods, you can use componentsSeparated(by:) to get an array of only string & only letters. Then, you can filter() (if needed), or compactMap() and transform to Int if possible, then sum (with reduce(into:_:).

As suggested, another solution without keeping a list of String could be:

var sum = 0
var lastWasNumber = false
var currentIntString = ""

for aCharacter in numsInStr {
if aCharacter.isNumber {
if !lastWasNumber {
sum += Int(currentIntString) ?? 0
currentIntString = "" // Reset, but in fact since we override with the next line, it's not necessary to write it
currentIntString = String(aCharacter)
} else {
currentIntString += String(aCharacter)
}
lastWasNumber = true
} else {
lastWasNumber = false
}
print("After processing: \(aCharacter) - got: \(currentIntString) - current sum: \(sum)")
}

sum += Int(currentIntString) ?? 0

print("Sum: \(sum)")

Here, we keep currentInString as a "buffer".

This could be simplified too by removing lastWasNumber and checking instead currentIntString:

var sum = 0
var currentIntString = ""

for aCharacter in numsInStr {
if aCharacter.isNumber {
if currentIntString.isEmpty {
currentIntString = String(aCharacter)
} else {
currentIntString += String(aCharacter)
}
} else {
sum += Int(currentIntString) ?? 0
currentIntString = ""
}
print("After processing: \(aCharacter) - got: \(currentIntString) - current sum: \(sum)")
}

sum += Int(currentIntString) ?? 0

print("Sum: \(sum)")


Related Topics



Leave a reply



Submit