Convertir la chaîne Swift en tableau


133

Comment puis-je convertir une chaîne "Hello" en un tableau ["H", "e", "l", "l", "o"] dans Swift?

En Objective-C, j'ai utilisé ceci:

NSMutableArray *characters = [[NSMutableArray alloc] initWithCapacity:[myString length]];
for (int i=0; i < [myString length]; i++) {
    NSString *ichar  = [NSString stringWithFormat:@"%c", [myString characterAtIndex:i]];
    [characters addObject:ichar];
}

Réponses:


339

C'est encore plus simple dans Swift:

let string : String = "Hello 🐶🐮 🇩🇪"
let characters = Array(string)
println(characters)
// [H, e, l, l, o,  , 🐶, 🐮,  , 🇩🇪]

Cela utilise les faits qui

  • un Arraypeut être créé à partir d'un SequenceType, et
  • Stringest conforme au SequenceTypeprotocole et son générateur de séquence énumère les caractères.

Et comme les chaînes Swift ont un support complet pour Unicode, cela fonctionne même avec des caractères en dehors du "Plan multilingue de base" (comme 🐶) et avec des clusters de graphèmes étendus (tels que 🇩🇪, qui est en fait composé de deux scalaires Unicode).


Mise à jour: à partir de Swift 2, String n'est plus conforme à SequenceType, mais la characterspropriété fournit une séquence de caractères Unicode:

let string = "Hello 🐶🐮 🇩🇪"
let characters = Array(string.characters)
print(characters)

Cela fonctionne également dans Swift 3 .


Mise à jour: Depuis Swift 4, String est (encore) une collection de ses Characters:

let string = "Hello 🐶🐮 🇩🇪"
let characters = Array(string)
print(characters)
// ["H", "e", "l", "l", "o", " ", "🐶", "🐮", " ", "🇩🇪"]

1
Avez-vous une idée de la raison pour laquelle essayer de join ( let joined = ", ".join(characters);) le tableau entraîne une 'String' is not identical to 'Character'erreur?
Mohamad

3
@Mohamad: l'énumération d'une chaîne produit une séquence de caractères, mais ", ".join(...)attend un tableau de chaînes. La réponse de devxoul ci-dessous montre comment vous pouvez vous diviser en un tableau de chaînes.
Martin R

2
@Fonix: charactersest une collection et une vue sur les chaînes de caractères. La création d'un tableau à partir des caractères fait une copie. - Bien sûr, on peut accéder directement aux personnages: for i in string.characters.indices { print(string.characters[i]) }ou tout simplementfor c in string.characters { print(c) }
Martin R

2
@Fonix: ... D'un autre côté, l'indexation aléatoire dans les chaînes peut être lente et il peut être avantageux de créer un tableau avec tous les caractères une fois. Exemple: stackoverflow.com/questions/40371929/… .
Martin R

2
@DaniSpringer: Swift 4 est actuellement en version bêta, vous aurez besoin de Xcode 9 beta: developer.apple.com/swift/resources .
Martin R

102

Modifier (Swift 4)

Dans Swift 4, vous n'avez pas besoin d'utiliser characterspour utiliser map(). Faites simplement map()sur String.

let letters = "ABC".map { String($0) }
print(letters) // ["A", "B", "C"]
print(type(of: letters)) // Array<String>

Ou si vous préférez plus court: "ABC".map(String.init)(2 octets 😀)

Modifier (Swift 2 et Swift 3)

Dans Swift 2 et Swift 3, vous pouvez utiliser la map()fonction pour la characterspropriété.

let letters = "ABC".characters.map { String($0) }
print(letters) // ["A", "B", "C"]

Original (Swift 1.x)

La réponse acceptée ne semble pas être la meilleure, car la conversion de séquence Stringn'est pas une Stringséquence, mais Character:

$ swift
Welcome to Swift!  Type :help for assistance.
  1> Array("ABC")
$R0: [Character] = 3 values {
  [0] = "A"
  [1] = "B"
  [2] = "C"
}

Ceci ci-dessous fonctionne pour moi:

let str = "ABC"
let arr = map(str) { s -> String in String(s) }

La référence pour une fonction globale map()est ici: http://swifter.natecook.com/func/map/


12
Légèrement plus court:arr = map(str) { String($0) }
Martin R

1
Utilisez Arrayplutôt l' initialiseur:Array("ABC".characters)
chrisamanse

1
@chrisamanse, Il n'y a pas de différence entre "ABC".characterset Array("ABC".characters).
devxoul

2
C'est différent dans Swift 3. "ABC".charactersrenvoie un type String.CharacterView. Pour le convertir en un tableau, spécifiquement de type [Character], vous devez utiliser l' Arrayinitialiseur dessus.
chrisamanse

2
@chrisamanse Oh, je ne le savais pas. J'avais tort. Merci de l'avoir signalé. Au fait, je voulais [String]plutôt [Character]parce que op voulait un tableau de chaînes :)
devxoul

22

Il existe également cette fonction utile sur String: components (sharedBy: String)

let string = "1;2;3"
let array = string.components(separatedBy: ";")
print(array) // returns ["1", "2", "3"]

Fonctionne bien pour traiter les chaînes séparées par un caractère comme ";" ou même "\ n"


8

Mis à jour pour Swift 4

Voici 3 façons.

//array of Characters
let charArr1 = [Character](myString)

//array of String.element
let charArr2 = Array(myString)

for char in myString {
  //char is of type Character
}

Dans certains cas, ce que les gens veulent vraiment, c'est un moyen de convertir une chaîne en un tableau de petites chaînes de 1 caractère chacune. Voici un moyen très efficace de le faire:

//array of String
var strArr = myString.map { String($0)}

Swift 3

Voici 3 façons.

let charArr1 = [Character](myString.characters)
let charArr2 = Array(myString.characters)
for char in myString.characters {
  //char is of type Character
}

Dans certains cas, ce que les gens veulent vraiment, c'est un moyen de convertir une chaîne en un tableau de petites chaînes de 1 caractère chacune. Voici un moyen très efficace de le faire:

var strArr = myString.characters.map { String($0)}

Ou vous pouvez ajouter une extension à String.

extension String {
   func letterize() -> [Character] {
     return Array(self.characters)
  }
}

Ensuite, vous pouvez l'appeler comme ceci:

let charArr = "Cat".letterize()


3

La réponse de Martin R est la meilleure approche, et comme il l'a dit, comme String est conforme au protocole SquenceType, vous pouvez également énumérer une chaîne, en obtenant chaque caractère à chaque itération.

let characters = "Hello"
var charactersArray: [Character] = []

for (index, character) in enumerate(characters) {
    //do something with the character at index
    charactersArray.append(character)
}

println(charactersArray)

2
Ou tout simplement for character in characters { charactersArray.append(character)}sans leenumeration()
Tieme

3

Dans Swift 4, tout comme Stringune collection de Character, vous devez utilisermap

let array1 = Array("hello") // Array<Character>
let array2 = Array("hello").map({ "\($0)" }) // Array<String>
let array3 = "hello".map(String.init) // Array<String>

3

Pour ce faire, vous pouvez facilement accéder à mapla variable et renvoyer chacun Charactersous la forme d'un String:

let someText = "hello"

let array = someText.map({ String($0) }) // [String]

La sortie doit être ["h", "e", "l", "l", "o"].


1

Vous pouvez également créer une extension:

var strArray = "Hello, playground".Letterize()

extension String {
    func Letterize() -> [String] {
        return map(self) { String($0) }
    }
}

1
func letterize() -> [Character] {
    return Array(self.characters)
}

2
Pouvez-vous fournir plus d'informations sur les raisons pour lesquelles cela fonctionnera? :)
pix

1
@pix Je pense qu'il voulait que cela soit une fonction définie dans une extension de String. J'ajouterai cela à ma réponse.
ScottyBlades

1

pour la fonction sur String: components (sharedBy: String)

dans Swift 5.1

avoir le changement pour:

string.split(separator: "/")

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.