Après avoir lu un fichier de taille moyenne (environ 500kByte) à partir d'un service web, j'ai une chaîne régulière Swift ( lines
) codé à l'origine dans .isolatin1
. Avant de le diviser effectivement, je voudrais compter le nombre de lignes (rapidement) afin de pouvoir initialiser une barre de progression.
Quel est le meilleur idiome Swift pour y parvenir ?
Je suis arrivé à la conclusion suivante :
let linesCount = lines.reduce(into: 0) { (count, letter) in
if letter == "\r\n" {
count += 1
}
}
Cela n'a pas l'air trop mal mais je me demande s'il n'y a pas un moyen plus court/rapide de le faire. Le site characters
permet d'accéder à une séquence de graphèmes Unicode qui traitent la propriété \r\n
comme une seule entité. Vérifier cela avec tous les CharacterSet.newlines
ne fonctionne pas, puisque CharacterSet
n'est pas un ensemble de Character
mais un ensemble de Unicode.Scalar
(de manière un peu contre-intuitive dans mon livre) qui est un ensemble de points de code (où \r\n compte pour deux points de code), pas graphèmes . Essayer
var lines = "Hello, playground\r\nhere too\r\nGalahad\r\n"
lines.unicodeScalars.reduce(into: 0) { (cnt, letter) in
if CharacterSet.newlines.contains(letter) {
cnt += 1
}
}
comptera jusqu'à 6 au lieu de 3. Cette méthode est donc plus générale que la précédente, mais elle ne fonctionnera pas correctement pour les fins de ligne CRLF.
Existe-t-il un moyen de permettre des conventions de fin de ligne plus nombreuses (comme dans CharacterSet.newlines
) qui donne toujours le bon résultat pour CRLF ? Le nombre de lignes peut-il être calculé avec moins de code (tout en restant lisible) ?