Konversi string Swift ke array

133

Bagaimana saya bisa mengubah string "Halo" menjadi array ["H", "e", "l", "l", "o"] di Swift?

Di Objective-C saya telah menggunakan ini:

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
sumber

Jawaban:

339

Lebih mudah lagi di Swift:

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

Ini menggunakan fakta-fakta itu

  • sebuah Arraydapat dibuat dari SequenceType, dan
  • Stringsesuai dengan SequenceTypeprotokol, dan generator urutannya menyebutkan karakter.

Dan karena string Swift memiliki dukungan penuh untuk Unicode, ini berfungsi bahkan dengan karakter di luar "Basic Multilingual Plane" (seperti 🐶) dan dengan cluster grapheme yang diperluas (seperti 🇩🇪, yang sebenarnya terdiri dari dua skalar Unicode).


Pembaruan: Pada Swift 2, String tidak lagi sesuai SequenceType, tetapi charactersproperti menyediakan urutan karakter Unicode:

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

Ini bekerja di Swift 3 juga.


Pembaruan: Pada Swift 4, String adalah (lagi) kumpulan dari Characters:

let string = "Hello 🐶🐮 🇩🇪"
let characters = Array(string)
print(characters)
// ["H", "e", "l", "l", "o", " ", "🐶", "🐮", " ", "🇩🇪"]
Martin R
sumber
1
Apakah Anda tahu mengapa mencoba bergabung ( let joined = ", ".join(characters);) menyebabkan 'String' is not identical to 'Character'kesalahan?
Mohamad
3
@Mohamad: Menghitung string menghasilkan urutan karakter, tetapi ", ".join(...)mengharapkan array string. Jawaban devxoul di bawah ini menunjukkan bagaimana Anda dapat memecah menjadi array string.
Martin R
2
@Fonix: charactersadalah koleksi dan tampilan karakter string. Membuat array dari karakter membuat salinan. - Tentu saja dapat mengakses karakter secara langsung: for i in string.characters.indices { print(string.characters[i]) }atau hanyafor c in string.characters { print(c) }
Martin R
2
@Fonix: ... Di sisi lain, pengindeksan acak ke dalam string bisa lambat dan menguntungkan untuk membuat array dengan semua karakter sekaligus. Contoh: stackoverflow.com/questions/40371929/… .
Martin R
2
@DaniSpringer: Swift 4 saat ini dalam versi beta, Anda akan memerlukan Xcode 9 beta: developer.apple.com/swift/resources .
Martin R
102

Edit (Swift 4)

Di Swift 4, Anda tidak harus menggunakan charactersuntuk menggunakannya map(). Lakukan saja map()pada String.

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

Atau jika Anda lebih suka lebih pendek: "ABC".map(String.init)(2-byte 😀)

Edit (Swift 2 & Swift 3)

Di Swift 2 dan Swift 3, Anda dapat menggunakan map()fungsi untuk charactersproperti.

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

Asli (Swift 1.x)

Jawaban yang diterima tampaknya bukan yang terbaik, karena urutan yang dikonversi Stringbukanlah Stringurutan, tetapi Character:

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

Ini di bawah ini berfungsi untuk saya:

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

Referensi untuk fungsi global map()ada di sini: http://swifter.natecook.com/func/map/

devxoul
sumber
12
Sedikit lebih pendek:arr = map(str) { String($0) }
Martin R
1
Gunakan Arrayinitializer sebagai gantinya:Array("ABC".characters)
chrisamanse
1
@ chrisamanse, Tidak ada perbedaan antara "ABC".charactersdan Array("ABC".characters).
devxoul
2
Ini berbeda dalam Swift 3. "ABC".charactersmengembalikan tipe String.CharacterView. Untuk mengonversinya menjadi sebuah array, khususnya tipe [Character],, Anda harus menggunakan Arrayinitializer di atasnya.
chrisamanse
2
@ Chrisamanse Oh, saya tidak tahu itu. Saya salah. Terima kasih telah menunjukkannya. Ngomong-ngomong, aku berniat [String]bukannya [Character]karena op ingin string array :)
devxoul
22

Ada juga fungsi yang berguna ini pada String: komponen (dipisahkan oleh: String)

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

Bekerja dengan baik untuk menangani string yang dipisahkan oleh karakter seperti ";" atau bahkan "\ n"

Frédéric Adda
sumber
8

Diperbarui untuk Swift 4

Inilah 3 cara.

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

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

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

Dalam beberapa kasus, yang benar-benar diinginkan orang adalah cara untuk mengubah string menjadi array string kecil dengan panjang masing-masing 1 karakter. Berikut adalah cara yang sangat efisien untuk melakukan itu:

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

Cepat 3

Inilah 3 cara.

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

Dalam beberapa kasus, yang benar-benar diinginkan orang adalah cara untuk mengubah string menjadi array string kecil dengan panjang masing-masing 1 karakter. Berikut adalah cara yang sangat efisien untuk melakukan itu:

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

Atau Anda dapat menambahkan ekstensi ke String.

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

Maka Anda dapat menyebutnya seperti ini:

let charArr = "Cat".letterize()
ScottyBlades
sumber
4
    let string = "hell0"
    let ar = Array(string.characters)
    print(ar)
William Hu
sumber
Tidak ada perubahan antara Swift 2 dan 3 sehubungan dengan masalah ini. Solusi ini identik dengan versi Swift 2 di stackoverflow.com/a/25921323/1187415 .
Martin R
3

Jawaban Martin R adalah pendekatan terbaik, dan seperti yang dia katakan, karena String sesuai dengan protokol SquenceType, Anda juga dapat menghitung string, mendapatkan setiap karakter pada setiap iterasi.

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
sumber
2
Atau hanya for character in characters { charactersArray.append(character)}tanpaenumeration()
Tieme
3

Di Swift 4, seperti Stringkoleksi Character, Anda perlu menggunakanmap

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

Cara mudah untuk melakukannya adalah dengan mapvariabel dan mengembalikan masing Character- masing sebagai String:

let someText = "hello"

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

Outputnya seharusnya ["h", "e", "l", "l", "o"].

atolit
sumber
1

Anda juga dapat membuat ekstensi:

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

extension String {
    func Letterize() -> [String] {
        return map(self) { String($0) }
    }
}
fabrizioM
sumber
1
func letterize() -> [Character] {
    return Array(self.characters)
}
Piotr Pszczółkowski
sumber
2
Bisakah Anda memberikan informasi lebih lanjut mengapa ini akan berhasil? :)
pix
1
@ix Saya pikir dia bermaksud untuk ini menjadi fungsi yang didefinisikan dalam ekstensi dari String. Saya akan menambahkan itu ke jawaban saya.
ScottyBlades
1

untuk fungsi pada String: komponen (dipisahkan oleh: String)

dalam Swift 5.1

ubah ke:

string.split(separator: "/")

Panda Gendut
sumber