Ce qui suit était possible avec Swift 2.2:
let m = "alpha"
for i in m.startIndex..<m.endIndex {
print(m[i])
}
a
l
p
h
a
Avec 3.0, nous obtenons l'erreur suivante:
Le type 'Range' (aka 'Range') n'est pas conforme au protocole 'Séquence'
J'essaie de faire une opération très simple avec des chaînes dans Swift - traverser simplement la première moitié de la chaîne (ou un problème plus générique: parcourir une plage de chaîne).
Je peux faire ce qui suit:
let s = "string"
var midIndex = s.index(s.startIndex, offsetBy: s.characters.count/2)
let r = Range(s.startIndex..<midIndex)
print(s[r])
Mais ici je ne traverse pas vraiment la corde. La question est donc de savoir comment parcourir une plage d'une chaîne donnée. Comme:
for i in Range(s.startIndex..<s.midIndex) {
print(s[i])
}
Vous pouvez traverser une chaîne en utilisant la propriété indices
de la propriété characters
comme ceci:
let letters = "string"
let middle = letters.index(letters.startIndex, offsetBy: letters.characters.count / 2)
for index in letters.characters.indices {
// to traverse to half the length of string
if index == middle { break } // s, t, r
print(letters[index]) // s, t, r, i, n, g
}
De la section documentation in Chaînes et caractères - Compter les caractères:
Les grappes de graphèmes étendus peuvent être composées d'un ou de plusieurs scalaires Unicode. Cela signifie que différents caractères, et différentes représentations du même caractère, peuvent nécessiter différentes quantités de mémoire à stocker. De ce fait, les caractères dans Swift n'occupent pas chacun la même quantité de mémoire dans la représentation d'une chaîne. En conséquence, le nombre de caractères d'une chaîne ne peut pas être calculé sans parcourir la chaîne afin de déterminer ses limites étendues de grappes de graphèmes.
l'emphase est à moi.
Cela ne fonctionnera pas:
let secondChar = letters[1]
// error: subscript is unavailable, cannot subscript String with an Int
Une autre option consiste à utiliser enumerated()
, par exemple:
let string = "Hello World"
for (index, char) in string.characters.enumerated() {
print(char)
}
ou pour Swift 4 simplement utiliser
let string = "Hello World"
for (index, char) in string.enumerated() {
print(char)
}
Utilisez le suivant:
for i in s.characters.indices[s.startIndex..<s.endIndex]
{
print(s[i])
}
Extrait de Migration vers Swift 2.3 ou Swift 3 depuis Swift 2.2
Itérer sur les caractères d'une chaîne est plus propre dans Swift 4:
let myString = "Hello World"
for char in myString {
print(char)
}
Si vous voulez parcourir les caractères d'une String
, au lieu d'accéder explicitement aux index de la String
, vous pouvez simplement utiliser le CharacterView
de la String
, qui est conforme à CollectionType
, vous permettant d'accéder pour mettre en ordre des méthodes de sous-séquençage telles que prefix(_:)
et ainsi de suite.
/* traverse the characters of your string instance,
up to middle character of the string, where "middle"
will be rounded down for strings of an odd amount of
characters (e.g. 5 characters -> travers through 2) */
let m = "alpha"
for ch in m.characters.prefix(m.characters.count/2) {
print(ch, ch.dynamicType)
} /* a Character
l Character */
/* round odd division up instead */
for ch in m.characters.prefix((m.characters.count+1)/2) {
print(ch, ch.dynamicType)
} /* a Character
l Character
p Character */
Si vous souhaitez traiter les caractères de la boucle comme des chaînes, utilisez simplement String(ch)
ci-dessus.
En ce qui concerne votre commentaire ci-dessous: si vous souhaitez accéder à une plage de CharacterView
, vous pouvez facilement implémenter votre propre extension de CollectionType
(spécifiée pour lorsque Generator.Element
est Character
) en utilisant à la fois prefix(_:)
et suffix(_:)
pour générer une sous-collection. donné par exemple une plage semi-ouverte (from..<to
)
/* for values to >= count, prefixed CharacterView will be suffixed until its end */
extension CollectionType where Generator.Element == Character {
func inHalfOpenRange(from: Int, to: Int) -> Self {
guard case let to = min(to, underestimateCount()) where from <= to else {
return self.prefix(0) as! Self
}
return self.prefix(to).suffix(to-from) as! Self
}
}
/* example */
let m = "0123456789"
for ch in m.characters.inHalfOpenRange(4, to: 8) {
print(ch) /* \ */
} /* 4 a (sub-collection) CharacterView
5
6
7 */
La meilleure façon de faire est: -
let name = "nick" // The String which we want to print.
for i in 0..<name.count
{
// Operation name[i] is not allowed in Swift, an alternative is
let index = name.index[name.startIndex, offsetBy: i]
print(name[index])
}
pour plus de détails, visitez ici
Swift 4.2
Simplement:
let m = "alpha"
for i in m.indices {
print(m[i])
}
Swift 4:
let mi: String = "hello how are you?"
for i in mi {
print(i)
}
Pour démontrer concrètement comment parcourir une plage d'une chaîne dans Swift 4, nous pouvons utiliser le filtre where
dans une boucle for
pour filtrer son exécution dans la plage spécifiée:
func iterateStringByRange(_ sentence: String, from: Int, to: Int) {
let startIndex = sentence.index(sentence.startIndex, offsetBy: from)
let endIndex = sentence.index(sentence.startIndex, offsetBy: to)
for position in sentence.indices where (position >= startIndex && position < endIndex) {
let char = sentence[position]
print(char)
}
}
iterateStringByRange("string", from: 1, to: 3)
imprimera t
, r
et i