Konvertieren Sie die Swift-Zeichenfolge in ein Array

133

Wie kann ich eine Zeichenfolge "Hallo" in Swift in ein Array ["H", "e", "l", "l", "o"] konvertieren?

In Objective-C habe ich Folgendes verwendet:

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];
}
Mr.KLD
quelle

Antworten:

338

In Swift ist es noch einfacher:

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

Dies nutzt die Fakten, die

  • ein Arraykann aus einem erstellt werdenSequenceType und erstellt werden
  • Stringentspricht dem SequenceTypeProtokoll und sein Sequenzgenerator zählt die Zeichen auf.

Und da Swift-Strings Unicode vollständig unterstützen, funktioniert dies auch mit Zeichen außerhalb der "Basic Multilingual Plane" (wie z. B. 🐶) und mit erweiterten Graphemclustern (wie z. B. 🇩🇪, die tatsächlich aus zwei Unicode-Skalaren bestehen).


Update: Ab Swift 2 String nicht mehr konform SequenceType, aber die charactersEigenschaft bietet eine Folge der Unicode-Zeichen:

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

Dies funktioniert auch in Swift 3 .


Update: Ab Swift 4 String ist (wieder) eine Sammlung seiner Characters:

let string = "Hello 🐶🐮 🇩🇪"
let characters = Array(string)
print(characters)
// ["H", "e", "l", "l", "o", " ", "🐶", "🐮", " ", "🇩🇪"]
Martin R.
quelle
1
Haben Sie eine Idee, warum der Versuch, let joined = ", ".join(characters);dem Array beizutreten ( ), zu einem führt ?'String' is not identical to 'Character' Fehler führt?
Mohamad
3
@ Mohamad: Das Aufzählen einer Zeichenfolge erzeugt eine Folge von Zeichen, ", ".join(...)erwartet jedoch ein Array von Zeichenfolgen. Die folgende Antwort von devxoul zeigt, wie Sie sich in eine Reihe von Zeichenfolgen aufteilen können.
Martin R
2
@Fonix: charactersist eine Sammlung und eine Ansicht der Zeichenfolgenzeichenfolgen. Durch das Erstellen eines Arrays aus den Zeichen wird eine Kopie erstellt. - Natürlich kann man direkt auf die Charaktere zugreifen: for i in string.characters.indices { print(string.characters[i]) }oder einfachfor c in string.characters { print(c) }
Martin R
2
@Fonix: ... Andererseits kann die zufällige Indizierung in Zeichenfolgen langsam sein und es kann vorteilhaft sein, ein Array mit allen Zeichen einmal zu erstellen. Beispiel: stackoverflow.com/questions/40371929/… .
Martin R
2
@DaniSpringer: Swift 4 befindet sich derzeit in der Beta-Version. Sie benötigen die Beta-Version von Xcode 9: developer.apple.com/swift/resources .
Martin R
102

Bearbeiten (Swift 4)

In Swift 4 müssen Sie nicht verwenden, um characterszu verwenden map(). Mach es einfach map()auf String.

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

Oder wenn Sie kürzer bevorzugen: "ABC".map(String.init)(2 Bytes 😀)

Bearbeiten (Swift 2 & Swift 3)

In Swift 2 und Swift 3 können Sie verwenden map() Funktion zur charactersEigenschaft verwenden.

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

Original (Swift 1.x)

Akzeptierte Antwort scheint nicht die beste zu sein, da sequenzkonvertiert Stringkeine StringSequenz ist, sondern Character:

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

Das unten funktioniert für mich:

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

Die Referenz für eine globale Funktion finden Sie map()hier: http://swifter.natecook.com/func/map/

devxoul
quelle
12
Etwas kürzer:arr = map(str) { String($0) }
Martin R
1
Verwenden Sie Arraystattdessen den Initialisierer:Array("ABC".characters)
Chrisamanse
1
@chrisamanse, Es gibt keinen Unterschied zwischen "ABC".charactersund Array("ABC".characters).
Devxoul
2
In Swift 3 ist das anders. "ABC".charactersGibt einen Typ zurück String.CharacterView. Um es in ein Array vom Typ "Typ" zu konvertieren, [Character]müssen Sie den ArrayInitialisierer verwenden.
Chrisamanse
2
@chrisamanse Oh, das wusste ich nicht. Ich lag falsch. Vielen Dank für den Hinweis. Übrigens wollte ich [String]statt [Character]weil op ein String Array wollte :)
devxoul
22

Es gibt auch diese nützliche Funktion für String: components (separateBy: String)

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

Funktioniert gut, um mit Zeichenfolgen umzugehen, die durch ein Zeichen wie ";" getrennt sind. oder sogar "\ n"

Frédéric Adda
quelle
8

Aktualisiert für Swift 4

Hier sind 3 Möglichkeiten.

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

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

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

In einigen Fällen möchten die Leute wirklich eine Möglichkeit, eine Zeichenfolge in ein Array kleiner Zeichenfolgen mit jeweils 1 Zeichen Länge umzuwandeln. Hier ist eine super effiziente Möglichkeit, dies zu tun:

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

Swift 3

Hier sind 3 Möglichkeiten.

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

In einigen Fällen möchten die Leute wirklich eine Möglichkeit, eine Zeichenfolge in ein Array kleiner Zeichenfolgen mit jeweils 1 Zeichen Länge umzuwandeln. Hier ist eine super effiziente Möglichkeit, dies zu tun:

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

Oder Sie können String eine Erweiterung hinzufügen.

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

Dann können Sie es so nennen:

let charArr = "Cat".letterize()
ScottyBlades
quelle
4
    let string = "hell0"
    let ar = Array(string.characters)
    print(ar)
William Hu
quelle
In Bezug auf dieses Problem gab es keine Änderungen zwischen Swift 2 und 3. Diese Lösung ist identisch mit der Swift 2-Version in stackoverflow.com/a/25921323/1187415 .
Martin R
3

Die Antwort von Martin R ist der beste Ansatz. Da String dem SquenceType-Protokoll entspricht, können Sie auch einen String auflisten, wobei jedes Zeichen bei jeder Iteration abgerufen wird.

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

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

println(charactersArray)
Alberto Barrera
quelle
2
Oder einfach for character in characters { charactersArray.append(character)}ohne dieenumeration()
Tieme
3

In Swift 4 müssen Sie wie Stringin einer Sammlung von Characterverwendenmap

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

Eine einfache Möglichkeit , dies zu tun ist , um mapdie Variable und zurück jeweils Characterals String:

let someText = "hello"

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

Die Ausgabe sollte sein ["h", "e", "l", "l", "o"].

Atolith
quelle
1

Sie können auch eine Erweiterung erstellen:

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

extension String {
    func Letterize() -> [String] {
        return map(self) { String($0) }
    }
}
fabrizioM
quelle
1
func letterize() -> [Character] {
    return Array(self.characters)
}
Piotr Pszczółkowski
quelle
2
Können Sie weitere Informationen dazu geben, warum dies funktioniert? :)
Bilder
1
@pix Ich denke, er wollte, dass dies eine Funktion ist, die in einer Erweiterung von String definiert ist. Ich werde das zu meiner Antwort hinzufügen.
ScottyBlades
1

für die Funktion für String: components (separateBy: String)

in Swift 5.1

habe geändert zu:

string.split(separator: "/")

Fetter Panda
quelle