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];
}

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", " ", "🐶", "🐮", " ", "🇩🇪"]

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/


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"


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()


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)

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>

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"].


1

Sie können auch eine Erweiterung erstellen:

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

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

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

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: "/")

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.