Chuyển đổi chuỗi Swift thành mảng


133

Làm cách nào tôi có thể chuyển đổi một chuỗi "Xin chào" thành một mảng ["H", "e", "l", "l", "o"] trong Swift?

Trong Mục tiêu-C tôi đã sử dụng điều này:

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

Câu trả lời:


338

Nó thậm chí còn dễ dàng hơn trong Swift:

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

Điều này sử dụng sự thật rằng

  • một Arraycó thể được tạo ra từ một SequenceType, và
  • Stringphù hợp với SequenceTypegiao thức, và trình tạo trình tự của nó liệt kê các ký tự.

Và vì các chuỗi Swift có hỗ trợ đầy đủ cho Unicode, nên chuỗi này hoạt động ngay cả với các ký tự bên ngoài "Mặt phẳng đa ngôn ngữ cơ bản" (như) và với các cụm grapheme mở rộng (như such, thực sự bao gồm hai vô hướng Unicode).


Cập nhật: Kể từ Swift 2, String không còn phù hợp với SequenceType, nhưng thuộc characterstính cung cấp một chuỗi các ký tự Unicode:

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

Điều này cũng hoạt động trong Swift 3 .


Cập nhật: Kể từ Swift 4, String (một lần nữa) là một bộ sưu tập của nó Character:

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

1
Bạn có biết tại sao cố gắng tham gia ( let joined = ", ".join(characters);) kết quả mảng bị 'String' is not identical to 'Character'lỗi không?
Mohamad

3
@Mohamad: Việc liệt kê một chuỗi tạo ra một chuỗi các ký tự, nhưng ", ".join(...)mong đợi một chuỗi các chuỗi. Câu trả lời của devxoul dưới đây cho thấy cách bạn có thể chia thành một chuỗi các chuỗi.
Martin R

2
@Fonix: characterslà một bộ sưu tập và chế độ xem các ký tự chuỗi. Tạo một mảng từ các ký tự tạo một bản sao. - Tất nhiên có thể truy cập trực tiếp vào các nhân vật: for i in string.characters.indices { print(string.characters[i]) }hoặc chỉfor c in string.characters { print(c) }
Martin R

2
@Fonix: ... Mặt khác, việc lập chỉ mục ngẫu nhiên thành các chuỗi có thể chậm và có thể thuận lợi khi tạo một mảng với tất cả các ký tự một lần. Ví dụ: stackoverflow.com/questions / 40371929 / hàn .
Martin R

2
@DaniSpringer: Swift 4 hiện đang ở giai đoạn thử nghiệm, bạn sẽ cần Xcode 9 beta: developer.apple.com/swift/resource .
Martin R

102

Chỉnh sửa (Swift 4)

Trong Swift 4, bạn không phải sử dụng charactersđể sử dụng map(). Chỉ cần làm map()trên String.

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

Hoặc nếu bạn muốn ngắn hơn: "ABC".map(String.init)(2 byte)

Chỉnh sửa (Swift 2 & Swift 3)

Trong Swift 2 và Swift 3, Bạn có thể sử dụng map()chức năng để characterssở hữu.

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

Bản gốc (Swift 1.x)

Câu trả lời được chấp nhận dường như không phải là tốt nhất, bởi vì chuyển đổi trình tự Stringkhông phải là một Stringchuỗi, nhưng Character:

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

Điều này dưới đây làm việc cho tôi:

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

Tham khảo cho một chức năng toàn cầu map()có tại đây: http://swifter.natecook.com/func/map/


12
Hơi ngắn hơn một chút:arr = map(str) { String($0) }
Martin R

1
Sử dụng trình Arraykhởi tạo thay thế:Array("ABC".characters)
chrisamanse

1
@chrisamanse, Không có sự khác biệt giữa "ABC".charactersArray("ABC".characters).
devxoul

2
Nó khác với Swift 3. "ABC".characterstrả về một loại String.CharacterView. Để chuyển đổi nó thành một mảng, cụ thể là kiểu [Character], bạn phải sử dụng trình Arraykhởi tạo trên nó.
chrisamanse

2
@chrisamanse Ồ, tôi không biết điều đó. Tôi đã sai. Cảm ơn đã chỉ ra điều đó. Nhân tiện, tôi dự định [String]thay [Character]vì vì op muốn một chuỗi chuỗi :)
devxoul

22

Ngoài ra còn có chức năng hữu ích này trên String: thành phần (separBy: String)

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

Hoạt động tốt để xử lý các chuỗi được phân tách bằng ký tự như ";" hoặc thậm chí "\ n"


8

Cập nhật cho Swift 4

Dưới đây là 3 cách.

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

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

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

Trong một số trường hợp, những gì mọi người thực sự muốn là một cách để chuyển đổi một chuỗi thành một chuỗi các chuỗi nhỏ với mỗi độ dài 1 ký tự. Đây là một cách siêu hiệu quả để làm điều đó:

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

Swift 3

Dưới đây là 3 cách.

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

Trong một số trường hợp, những gì mọi người thực sự muốn là một cách để chuyển đổi một chuỗi thành một chuỗi các chuỗi nhỏ với mỗi độ dài 1 ký tự. Đây là một cách siêu hiệu quả để làm điều đó:

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

Hoặc bạn có thể thêm một phần mở rộng cho String.

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

Sau đó, bạn có thể gọi nó như thế này:

let charArr = "Cat".letterize()


3

Câu trả lời của Martin R là cách tiếp cận tốt nhất, và như ông đã nói, bởi vì String tuân thủ giao thức SquenceType, bạn cũng có thể liệt kê một chuỗi, nhận từng ký tự trên mỗi lần lặp.

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
Hoặc chỉ cần for character in characters { charactersArray.append(character)}không cóenumeration()
Tieme

3

Trong Swift 4, như Stringlà một bộ sưu tập Character, bạn cần sử dụngmap

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

3

Một cách dễ dàng để làm điều này là mapbiến và trả về mỗi biến CharacterString:

let someText = "hello"

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

Đầu ra phải là ["h", "e", "l", "l", "o"].


1

Bạn cũng có thể tạo tiện ích mở rộng:

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

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

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

2
Bạn có thể cung cấp thêm thông tin tại sao điều này sẽ làm việc? :)
pix

1
@pix Tôi nghĩ rằng ý của anh ta là đây là một hàm được định nghĩa trong phần mở rộng của String. Tôi sẽ thêm nó vào câu trả lời của tôi.
ScottyBlades

1

cho hàm trên String: thành phần (separBy: String)

trong Swift 5.1

đã thay đổi thành:

string.split(separator: "/")

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.