แปลงสตริง Swift เป็นอาร์เรย์


143

ฉันจะแปลงสตริง "Hello" เป็นอาร์เรย์ ["H", "e", "l", "l", "o"] ใน Swift ได้อย่างไร

ใน Objective-C ฉันได้ใช้สิ่งนี้:

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

คำตอบ:


359

ง่ายยิ่งขึ้นใน Swift:

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

ซึ่งใช้ข้อเท็จจริงว่า

  • Arrayสามารถสร้างขึ้นจากSequenceTypeและ
  • Stringเป็นไปตามSequenceTypeโปรโตคอลและตัวสร้างลำดับจะแจกแจงอักขระ

และเนื่องจากสตริง Swift มีการสนับสนุน Unicode อย่างสมบูรณ์สิ่งนี้จึงใช้ได้แม้กับอักขระที่อยู่นอก "Basic Multilingual Plane" (เช่น🐶) และกับคลัสเตอร์ grapheme แบบขยาย (เช่น🇩🇪ซึ่งประกอบด้วยสเกลาร์ Unicode สองตัว )


อัปเดต: ในขณะที่ Swift 2 Stringไม่สอดคล้องกับอีกต่อไป SequenceTypeแต่charactersคุณสมบัติจะจัดเตรียมลำดับของอักขระ Unicode

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

ซึ่งใช้งานได้ในSwift 3เช่นกัน


อัปเดต: ในขณะที่ Swift 4 Stringเป็นคอลเล็กชันของมัน (อีกครั้ง) Character:

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

1
คุณมีความคิดว่าเหตุใดการพยายามเข้าร่วม ( let joined = ", ".join(characters);) อาร์เรย์จึงเกิด'String' is not identical to 'Character'ข้อผิดพลาด
Mohamad

3
@ Mohamad: การแจกแจงสตริงจะสร้างลำดับของอักขระ แต่", ".join(...)คาดว่าจะมีอาร์เรย์ของสตริง คำตอบของ devxoul ด้านล่างแสดงให้เห็นว่าคุณสามารถแบ่งออกเป็นอาร์เรย์ของสตริงได้อย่างไร
Martin R

2
@Fonix: charactersเป็นคอลเลกชันและมุมมองเกี่ยวกับอักขระสตริง การสร้างอาร์เรย์จากอักขระจะทำสำเนา - แน่นอนสามารถเข้าถึงตัวละครได้โดยตรง: for i in string.characters.indices { print(string.characters[i]) }หรือเพียงแค่for c in string.characters { print(c) }
Martin R

2
@Fonix: ... ในทางกลับกันการสร้างดัชนีแบบสุ่มในสตริงอาจทำได้ช้าและอาจเป็นประโยชน์ในการสร้างอาร์เรย์ที่มีอักขระทั้งหมดเพียงครั้งเดียว ตัวอย่าง: stackoverflow.com/questions/40371929/… .
Martin R

2
@DaniSpringer: สวิฟท์ 4 ขณะนี้อยู่ในรุ่นเบต้าคุณจะต้อง Xcode 9 เบต้า: developer.apple.com/swift/resources
Martin R

104

แก้ไข (Swift 4)

ในสวิฟท์ 4 คุณจะได้ไม่ต้องใช้กับการใช้งานcharacters map()เพียงแค่ทำmap()ใน String

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

หรือถ้าคุณต้องการให้สั้นกว่านี้: "ABC".map(String.init)(2-bytes 😀)

แก้ไข (Swift 2 & Swift 3)

ใน Swift 2 และ Swift 3 คุณสามารถใช้map()ฟังก์ชันเพื่อcharactersคุณสมบัติ

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

ต้นฉบับ (Swift 1.x)

คำตอบที่ได้รับการยอมรับดูเหมือนจะไม่ดีที่สุดเพราะลำดับที่แปลงStringไม่ใช่Stringลำดับ แต่Character:

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

ด้านล่างนี้ใช้ได้กับฉัน:

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

ข้อมูลอ้างอิงสำหรับฟังก์ชันส่วนกลางmap()อยู่ที่นี่: http://swifter.natecook.com/func/map/


12
สั้นกว่าเล็กน้อย:arr = map(str) { String($0) }
Martin R

1
ใช้Arrayinitializer แทน:Array("ABC".characters)
chrisamanse

1
@chrisamanse มีความแตกต่างระหว่างไม่ได้และ"ABC".characters Array("ABC".characters)
devxoul

2
มันแตกต่างกันในสวิฟท์ 3. ผลตอบแทนประเภท"ABC".characters String.CharacterViewในการแปลงเป็นอาร์เรย์โดยเฉพาะประเภท[Character]คุณต้องใช้Arrayinitializer กับมัน
chrisamanse

2
@chrisamanse โอ้ฉันไม่รู้ ฉันผิดไป. ขอบคุณที่ชี้ให้เห็น อย่างไรก็ตามฉันตั้งใจ[String]แทนที่จะเป็น[Character]เพราะ op ต้องการอาร์เรย์สตริง :)
devxoul

23

นอกจากนี้ยังมีฟังก์ชั่นที่มีประโยชน์นี้ใน String: components (SeparatedBy: String)

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

ทำงานได้ดีกับสตริงที่คั่นด้วยอักขระเช่น ";" หรือแม้แต่ "\ n"


8

อัปเดตสำหรับ Swift 4

มี 3 วิธีดังนี้

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

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

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

ในบางกรณีสิ่งที่ผู้คนต้องการจริงๆคือวิธีการแปลงสตริงเป็นอาร์เรย์ของสตริงขนาดเล็กโดยมีความยาวอักขระ 1 ตัว นี่คือวิธีที่มีประสิทธิภาพสูงในการทำเช่นนั้น:

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

สวิฟต์ 3

มี 3 วิธีดังนี้

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

ในบางกรณีสิ่งที่ผู้คนต้องการจริงๆคือวิธีการแปลงสตริงเป็นอาร์เรย์ของสตริงขนาดเล็กโดยมีความยาวอักขระ 1 ตัว นี่คือวิธีที่มีประสิทธิภาพสูงในการทำเช่นนั้น:

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

หรือคุณสามารถเพิ่มส่วนขยายใน String

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

จากนั้นคุณสามารถเรียกสิ่งนี้ว่า:

let charArr = "Cat".letterize()

4
    let string = "hell0"
    let ar = Array(string.characters)
    print(ar)

ไม่มีการเปลี่ยนแปลงระหว่าง Swift 2 และ 3 เกี่ยวกับปัญหานี้ การแก้ปัญหานี้เป็นเหมือนรุ่นสวิฟท์ 2 ในstackoverflow.com/a/25921323/1187415
Martin R

4

วิธีง่ายๆในการทำเช่นนี้คือไปmapที่ตัวแปรและส่งคืนแต่ละตัวแปรCharacterเป็นString:

let someText = "hello"

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

["h", "e", "l", "l", "o"]เอาท์พุทควรจะเป็น


3

คำตอบของ Martin R เป็นแนวทางที่ดีที่สุดและอย่างที่เขาพูดเนื่องจาก String เป็นไปตามโปรโตคอล SquenceType คุณยังสามารถระบุสตริงโดยรับอักขระแต่ละตัวในการวนซ้ำแต่ละครั้ง

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
หรือfor character in characters { charactersArray.append(character)}ไม่มีenumeration()
Tieme

3

ใน Swift 4 คุณจำเป็นต้องใช้เช่นเดียวStringกับคอลเลคชันCharactermap

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

1

คุณยังสามารถสร้างส่วนขยาย:

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

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

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

2
คุณสามารถให้ข้อมูลเพิ่มเติมได้หรือไม่ว่าเหตุใดจึงได้ผล :)
Pix

1
@pix ฉันคิดว่าเขาตั้งใจให้สิ่งนี้เป็นฟังก์ชันที่กำหนดไว้ในส่วนขยายของ String ฉันจะเพิ่มคำตอบนั้น
ScottyBlades


0

สมมติว่าคุณมีช่องข้อความสี่ช่อง "otpOneTxt", "otpTwoTxt", "otpThreeTxt", "otpFourTxt" และสตริง "getOtp"

            let getup = "5642"
            let array = self.getOtp.map({ String($0) })
            
            otpOneTxt.text = array[0] //5
           
            otpTwoTxt.text = array[1] //6
           
            otpThreeTxt.text = array[2] //4
            
            otpFourTxt.text = array[3] //2
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.