J'ai besoin d'extraire des nombres d'une chaîne et de les mettre dans un nouveau tableau dans Swift.
var str = "I have to buy 3 apples, 7 bananas, 10eggs"
J'ai essayé de boucler chaque personnage et je n'ai aucune idée de comparer entre Characters et Int.
Tout d'abord, nous divisons la chaîne afin de pouvoir traiter les éléments individuels. Ensuite, nous utilisons NSCharacterSet
pour sélectionner les nombres uniquement.
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)")
}
}
Swift 3/4
let string = "0kaksd020dk2kfj2123"
if let number = Int(string.components(separatedBy: CharacterSet.decimalDigits.inverted).joined()) {
// Do something with this number
}
Vous pouvez aussi faire une extension comme:
extension Int {
static func parse(from string: String) -> Int? {
return Int(string.components(separatedBy: CharacterSet.decimalDigits.inverted).joined())
}
}
Et ensuite, utilisez-le comme:
if let number = Int.parse(from: "0kaksd020dk2kfj2123") {
// Do something with this number
}
let str = "Hello 1, World 62"
let intString = str.componentsSeparatedByCharactersInSet(
NSCharacterSet
.decimalDigitCharacterSet()
.invertedSet)
.joinWithSeparator("")
Cela vous donnera une chaîne avec tout le nombre alors vous pouvez simplement faire ceci:
let int = Int(intString)
Assurez-vous juste de le déballer car let int = Int(intString)
est une option.
Utilisation de la "fonction d'assistance regex" de Swift extrait des expressions rationnelles correspond :
func matchesForRegexInText(regex: String!, text: String!) -> [String] {
let regex = NSRegularExpression(pattern: regex,
options: nil, error: nil)!
let nsString = text as NSString
let results = regex.matchesInString(text,
options: nil, range: NSMakeRange(0, nsString.length))
as! [NSTextCheckingResult]
return map(results) { nsString.substringWithRange($0.range)}
}
vous pouvez y arriver facilement avec
let str = "I have to buy 3 apples, 7 bananas, 10eggs"
let numbersAsStrings = matchesForRegexInText("\\d+", str) // [String]
let numbersAsInts = numbersAsStrings.map { $0.toInt()! } // [Int]
println(numbersAsInts) // [3, 7, 10]
Le modèle "\d+"
correspond à un ou plusieurs chiffres décimaux.
Bien sûr, la même chose peut être faite sans l'utilisation d'une fonction d'assistance Si vous préférez cela pour une raison quelconque:
let str = "I have to buy 3 apples, 7 bananas, 10eggs"
let regex = NSRegularExpression(pattern: "\\d+", options: nil, error: nil)!
let nsString = str as NSString
let results = regex.matchesInString(str, options: nil, range: NSMakeRange(0, nsString.length))
as! [NSTextCheckingResult]
let numbers = map(results) { nsString.substringWithRange($0.range).toInt()! }
println(numbers) // [3, 7, 10]
Solution alternative sans expressions régulières:
let str = "I have to buy 3 apples, 7 bananas, 10eggs"
let digits = "0123456789"
let numbers = split(str, allowEmptySlices: false) { !contains(digits, $0) }
.map { $0.toInt()! }
println(numbers) // [3, 7, 10]
Swift 2.2
let strArr = str.characters.split{$0 == " "}.map(String.init)
for item in strArr {
let components = item.componentsSeparatedByCharactersInSet(NSCharacterSet.decimalDigitCharacterSet().invertedSet)
let part = components.joinWithSeparator("")
if let intVal = Int(part) {
print("this is a number -> \(intVal)")
}
}
// This will only work with single digit numbers. Works with “10eggs” (no space between number and Word
var str = "I have to buy 3 apples, 7 bananas, 10eggs"
var ints: [Int] = []
for char:Character in str {
if let int = "\(char)".toInt(){
ints.append(int)
}
}
Le truc, c’est que vous pouvez vérifier si une chaîne est un entier (mais vous ne pouvez pas vérifier si un caractère est) . En passant en boucle chaque caractère de la chaîne, utilisez une interpolation de chaîne pour créer une chaîne à partir du caractère et vérifie si cette chaîne cas est convertie en entier.
Si cela est possible, ajoutez-le au tableau.
// This will work with multi digit numbers. Does NOT work with “10 eggs” (has to have a space between number and Word)
var str = "I have to buy 3 apples, 7 bananas, 10 eggs"
var ints: [Int] = []
var strArray = split(str) {$0 == " "}
for subString in strArray{
if let int = subString.toInt(){
ints.append(int)
}
}
Ici, nous séparons la chaîne à n’importe quel espace et créons un tableau de toutes les sous-chaînes de la chaîne longue.
Nous vérifions à nouveau chaque chaîne pour voir si elle est (ou peut être convertie comme) un entier.
En m'adaptant à partir de answer , .__, de @ flashadvanced, les éléments suivants sont plus courts et plus simples.
let str = "I have to buy 3 apples, 7 bananas, 10eggs"
let component = str.componentsSeparatedByCharactersInSet(NSCharacterSet.decimalDigitCharacterSet().invertedSet)
let list = component.filter({ $0 != "" }) // filter out all the empty strings in the component
print(list)
Essayé dans le terrain de jeu et ça marche
J'espère que ça aide :)
Merci à tous ceux qui ont répondu à ma question.
Je cherchais un bloc de code qui utilise uniquement la grammaire Swift, car j'apprends la grammaire seulement maintenant.
J'ai une réponse à ma question. Peut-être que ce n'est pas un moyen plus facile de résoudre le problème, mais il utilise uniquement le langage Swift.
var article = "I have to buy 3 apples, 7 bananas, 10 eggs"
var charArray = Array(article)
var unitValue = 0
var total = 0
for char in charArray.reverse() {
if let number = "\(char)".toInt() {
if unitValue==0 {
unitValue = 1
}
else {
unitValue *= 10
}
total += number*unitValue
}
else {
unitValue = 0
}
}
println("I bought \(total) apples.")