การค้นหาดัชนีของตัวละครใน Swift String


203

ถึงเวลาที่จะยอมรับความพ่ายแพ้ ...

ใน Objective-C ฉันสามารถใช้สิ่งที่ชอบ:

NSString* str = @"abcdefghi";
[str rangeOfString:@"c"].location; // 2

ใน Swift ฉันเห็นบางสิ่งที่คล้ายกัน:

var str = "abcdefghi"
str.rangeOfString("c").startIndex

... แต่นั่นให้ฉันเพียงอันString.Indexเดียวซึ่งฉันสามารถใช้เพื่อห้อยกลับเข้าไปในสตริงเดิม แต่ไม่สามารถแยกตำแหน่งที่ตั้งออกมาได้

FWIW ที่String.Indexมี ivar ส่วนตัวที่เรียก_positionว่ามีค่าที่ถูกต้องในนั้น ฉันแค่ไม่เห็นว่ามันสัมผัสได้อย่างไร

ฉันรู้ว่าฉันสามารถเพิ่มสิ่งนี้ลงใน String ได้อย่างง่ายดาย ฉันอยากรู้เพิ่มเติมเกี่ยวกับสิ่งที่ฉันหายไปใน API ใหม่นี้


นี่คือโครงการ GitHub ที่มีวิธีการขยายจำนวนมากสำหรับการจัดการสตริง Swift: github.com/iamjono/SwiftString
RenniePet

การใช้งานที่ดีที่สุดที่ฉันพบอยู่ที่นี่: stackoverflow.com/a/32306142/4550651
Carlos García

คุณต้องการแยกแยะระหว่าง Unicode Codepoints และ Extended Grapheme Clusters หรือไม่?
Ben Leggiero

คำตอบ:


248

คุณไม่ใช่คนเดียวที่หาทางออกไม่ได้

StringRandomAccessIndexTypeไม่ใช้ อาจเป็นเพราะพวกเขาเปิดใช้งานอักขระที่มีความยาวไบต์ต่างกัน นั่นเป็นเหตุผลที่เราต้องใช้string.characters.count( countหรือcountElementsใน Swift 1.x) เพื่อรับจำนวนตัวอักษร ที่ยังใช้กับตำแหน่ง _positionอาจเป็นดัชนีลงในอาร์เรย์ดิบไบต์และพวกเขาไม่ต้องการที่จะเปิดเผยว่า String.Indexจะหมายถึงการปกป้องเราจากการเข้าถึงไบต์ในช่วงกลางของตัวละคร

นั่นหมายความว่าคุณจะต้องสร้างดัชนีใด ๆ จากString.startIndexหรือString.endIndex( String.IndexดำเนินการBidirectionalIndexType) สามารถสร้างดัชนีอื่นใดโดยใช้successorหรือpredecessorวิธีการ

ตอนนี้เพื่อช่วยเราด้วยดัชนีมีชุดวิธีการ (ฟังก์ชั่นใน Swift 1.x):

Swift 4.x

let text = "abc"
let index2 = text.index(text.startIndex, offsetBy: 2) //will call succ 2 times
let lastChar: Character = text[index2] //now we can index!

let characterIndex2 = text.index(text.startIndex, offsetBy: 2)
let lastChar2 = text[characterIndex2] //will do the same as above

let range: Range<String.Index> = text.range(of: "b")!
let index: Int = text.distance(from: text.startIndex, to: range.lowerBound)

Swift 3.0

let text = "abc"
let index2 = text.index(text.startIndex, offsetBy: 2) //will call succ 2 times
let lastChar: Character = text[index2] //now we can index!

let characterIndex2 = text.characters.index(text.characters.startIndex, offsetBy: 2)
let lastChar2 = text.characters[characterIndex2] //will do the same as above

let range: Range<String.Index> = text.range(of: "b")!
let index: Int = text.distance(from: text.startIndex, to: range.lowerBound)

สวิฟท์ 2.x

let text = "abc"
let index2 = text.startIndex.advancedBy(2) //will call succ 2 times
let lastChar: Character = text[index2] //now we can index!
let lastChar2 = text.characters[index2] //will do the same as above

let range: Range<String.Index> = text.rangeOfString("b")!
let index: Int = text.startIndex.distanceTo(range.startIndex) //will call successor/predecessor several times until the indices match

สวิฟท์ 1.x

let text = "abc"
let index2 = advance(text.startIndex, 2) //will call succ 2 times
let lastChar: Character = text[index2] //now we can index!

let range = text.rangeOfString("b")
let index: Int = distance(text.startIndex, range.startIndex) //will call succ/pred several times

การทำงานกับString.Indexยุ่งยาก แต่ใช้ wrapper เพื่อจัดทำดัชนีโดยจำนวนเต็ม (ดูhttps://stackoverflow.com/a/25152652/669586 ) เป็นสิ่งที่อันตรายเพราะซ่อนความไร้ประสิทธิภาพของการจัดทำดัชนีจริง

โปรดทราบว่าการใช้งานการจัดทำดัชนี Swift มีปัญหาที่ดัชนี / ช่วงที่สร้างขึ้นสำหรับสตริงหนึ่งไม่สามารถใช้กับสตริงอื่นได้อย่างน่าเชื่อถือตัวอย่างเช่น:

สวิฟท์ 2.x

let text: String = "abc"
let text2: String = "🎾🏇🏈"

let range = text.rangeOfString("b")!

//can randomly return a bad substring or throw an exception
let substring: String = text2[range]

//the correct solution
let intIndex: Int = text.startIndex.distanceTo(range.startIndex)
let startIndex2 = text2.startIndex.advancedBy(intIndex)
let range2 = startIndex2...startIndex2

let substring: String = text2[range2]

สวิฟท์ 1.x

let text: String = "abc"
let text2: String = "🎾🏇🏈"

let range = text.rangeOfString("b")

//can randomly return nil or a bad substring 
let substring: String = text2[range] 

//the correct solution
let intIndex: Int = distance(text.startIndex, range.startIndex)    
let startIndex2 = advance(text2.startIndex, intIndex)
let range2 = startIndex2...startIndex2

let substring: String = text2[range2]  

1
อึดอัดใจคิดว่าอาจเป็นเช่นนี้ดูเหมือนจะเป็นคำตอบ หวังว่าฟังก์ชันสองช่วงเหล่านี้จะทำให้มันเป็นเอกสารบางครั้งก่อนที่จะปล่อยรุ่นสุดท้าย
Matt Wilding

ประเภทใดที่อยู่rangeในvar range = text.rangeOfString("b")
zaph

5
@Zaph ทุกคนมีCollection typealias IndexTypeสำหรับอาร์เรย์มันถูกกำหนดให้เป็นIntสำหรับมันถูกกำหนดให้เป็นString String.Indexทั้งอาร์เรย์และสตริงยังสามารถใช้ช่วง (เพื่อสร้าง subarrays และสตริงย่อย) Range<T>ช่วงที่เป็นชนิดพิเศษ สำหรับสตริงก็สำหรับอาร์เรย์Range<String.Index> Range<Int>
Sulthan

1
ในSwift 2.0, distance(text.startIndex, range.startIndex)กลายเป็นtext.startIndex.distanceTo(range.startIndex)
superarts.org

1
@devios Stringเหมือนในมูลนิธิมีวิธีการที่เรียกว่าNSString hasPrefix(_:)
Sulthan

86

Swift 3.0ทำให้สิ่งนี้ละเอียดยิ่งขึ้นอีกเล็กน้อย:

let string = "Hello.World"
let needle: Character = "."
if let idx = string.characters.index(of: needle) {
    let pos = string.characters.distance(from: string.startIndex, to: idx)
    print("Found \(needle) at position \(pos)")
}
else {
    print("Not found")
}

ส่วนขยาย:

extension String {
    public func index(of char: Character) -> Int? {
        if let idx = characters.index(of: char) {
            return characters.distance(from: startIndex, to: idx)
        }
        return nil
    }
}

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

let string = "Hello.World"
let needle: Character = "."
if let idx = string.characters.indexOf(needle) {
    let pos = string.startIndex.distanceTo(idx)
    print("Found \(needle) at position \(pos)")
}
else {
    print("Not found")
}

ส่วนขยาย:

extension String {
    public func indexOfCharacter(char: Character) -> Int? {
        if let idx = self.characters.indexOf(char) {
            return self.startIndex.distanceTo(idx)
        }
        return nil
    }
}

การติดตั้ง Swift 1.x:

สำหรับโซลูชัน Swift ที่บริสุทธิ์เราสามารถใช้:

let string = "Hello.World"
let needle: Character = "."
if let idx = find(string, needle) {
    let pos = distance(string.startIndex, idx)
    println("Found \(needle) at position \(pos)")
}
else {
    println("Not found")
}

ในฐานะส่วนขยายของString:

extension String {
    public func indexOfCharacter(char: Character) -> Int? {
        if let idx = find(self, char) {
            return distance(self.startIndex, idx)
        }
        return nil
    }
}

1
ตัวอักษรเลิกใช้แล้ว !!
Shivam Pokhriyal

23
extension String {

    // MARK: - sub String
    func substringToIndex(index:Int) -> String {
        return self.substringToIndex(advance(self.startIndex, index))
    }
    func substringFromIndex(index:Int) -> String {
        return self.substringFromIndex(advance(self.startIndex, index))
    }
    func substringWithRange(range:Range<Int>) -> String {
        let start = advance(self.startIndex, range.startIndex)
        let end = advance(self.startIndex, range.endIndex)
        return self.substringWithRange(start..<end)
    }

    subscript(index:Int) -> Character{
        return self[advance(self.startIndex, index)]
    }
    subscript(range:Range<Int>) -> String {
        let start = advance(self.startIndex, range.startIndex)
            let end = advance(self.startIndex, range.endIndex)
            return self[start..<end]
    }


    // MARK: - replace
    func replaceCharactersInRange(range:Range<Int>, withString: String!) -> String {
        var result:NSMutableString = NSMutableString(string: self)
        result.replaceCharactersInRange(NSRange(range), withString: withString)
        return result
    }
}

7
คิดเกี่ยวกับการทำเช่นนี้ แต่ฉันคิดว่ามันเป็นปัญหาที่ซ่อนความหมายของการเข้าถึงสตริง ลองนึกภาพการสร้าง API สำหรับการเข้าถึงรายการที่เชื่อมโยงซึ่งดูเหมือนกับ API สำหรับอาร์เรย์ ผู้คนต้องการเขียนโค้ดที่ไม่มีประสิทธิภาพอย่างน่ากลัว
Erik Engheim

16

ฉันได้พบวิธีแก้ปัญหานี้สำหรับ swift2:

var str = "abcdefghi"
let indexForCharacterInString = str.characters.indexOf("c") //returns 2

สิ่งที่จะเป็นดัชนีเมื่อ str = "abcdefgchi"
Vatsal Shukla

10

สวิฟท์ 5.0

public extension String {  
  func indexInt(of char: Character) -> Int? {
    return firstIndex(of: char)?.utf16Offset(in: self)
  }
}

Swift 4.0

public extension String {  
  func indexInt(of char: Character) -> Int? {
    return index(of: char)?.encodedOffset        
  }
}

ดัชนีส่งคืน (จาก: องค์ประกอบ). แผนที่ {target.distance (จาก: startIndex ถึง: $ 0)}
frogcjn

8

ฉันไม่แน่ใจว่าจะดึงตำแหน่งออกจาก String.Index ได้อย่างไร แต่ถ้าคุณยินดีที่จะถอยกลับในกรอบบาง Objective-C คุณสามารถเชื่อมโยงไปยังวัตถุประสงค์ -c และทำเช่นเดียวกับที่คุณเคยทำ

"abcdefghi".bridgeToObjectiveC().rangeOfString("c").location

ดูเหมือนว่าบางวิธี NSString ยังไม่ได้รับการย้าย (หรืออาจจะไม่) ไปยัง String ประกอบด้วยยังอยู่ในใจ


ปรากฏว่าการเข้าถึงคุณสมบัติตำแหน่งของค่าส่งคืนนั้นเพียงพอสำหรับคอมไพเลอร์เพื่ออนุมานชนิด NSString ดังนั้นจึงbridgeToObjectiveC()ไม่จำเป็นต้องมีการโทร ดูเหมือนว่าปัญหาของฉันจะปรากฏเฉพาะเมื่อเรียกrangeOfStringใช้ Swift String ที่มีอยู่ก่อนหน้านี้ ดูเหมือนว่าปัญหา API ...
แมตต์ไวล์ดิ้ง

นั่นดูน่าสนใจ. ฉันไม่รู้ว่ามันสรุปในกรณีเหล่านั้น เมื่อเป็น String แล้วคุณสามารถใช้สะพานได้ตลอดเวลา
Connor

8

นี่คือส่วนขยายสตริงที่สะอาดที่ตอบคำถาม:

สวิฟท์ 3:

extension String {
    var length:Int {
        return self.characters.count
    }

    func indexOf(target: String) -> Int? {

        let range = (self as NSString).range(of: target)

        guard range.toRange() != nil else {
            return nil
        }

        return range.location

    }
    func lastIndexOf(target: String) -> Int? {



        let range = (self as NSString).range(of: target, options: NSString.CompareOptions.backwards)

        guard range.toRange() != nil else {
            return nil
        }

        return self.length - range.location - 1

    }
    func contains(s: String) -> Bool {
        return (self.range(of: s) != nil) ? true : false
    }
}

สวิฟท์ 2.2:

extension String {    
    var length:Int {
        return self.characters.count
    }

    func indexOf(target: String) -> Int? {

        let range = (self as NSString).rangeOfString(target)

        guard range.toRange() != nil else {
            return nil
        }

        return range.location

    }
    func lastIndexOf(target: String) -> Int? {



        let range = (self as NSString).rangeOfString(target, options: NSStringCompareOptions.BackwardsSearch)

        guard range.toRange() != nil else {
            return nil
        }

        return self.length - range.location - 1

    }
    func contains(s: String) -> Bool {
        return (self.rangeOfString(s) != nil) ? true : false
    }
}

7

คุณยังสามารถค้นหาดัชนีของตัวละครในสตริงเดียวเช่นนี้

extension String {

  func indexes(of character: String) -> [Int] {

    precondition(character.count == 1, "Must be single character")

    return self.enumerated().reduce([]) { partial, element  in
      if String(element.element) == character {
        return partial + [element.offset]
      }
      return partial
    }
  }

}

ซึ่งให้ผลลัพธ์เป็น [String.Distance] เช่น [Int] เช่น

"apple".indexes(of: "p") // [1, 2]
"element".indexes(of: "e") // [0, 2, 4]
"swift".indexes(of: "j") // []

5

หากคุณต้องการใช้ NSString ที่คุ้นเคยคุณสามารถประกาศได้อย่างชัดเจน:

var someString: NSString = "abcdefghi"

var someRange: NSRange = someString.rangeOfString("c")

ฉันยังไม่แน่ใจว่าจะทำอย่างไรใน Swift


1
วิธีนี้ใช้ได้ผลและดูเหมือนว่าคอมไพเลอร์ค่อนข้างก้าวร้าวในการอนุมานประเภท NSString สำหรับคุณ ฉันหวังเป็นอย่างยิ่งว่าจะใช้วิธีการที่รวดเร็วอย่างแท้จริงในการทำสิ่งนี้เนื่องจากดูเหมือนว่าเป็นกรณีการใช้งานทั่วไปที่เพียงพอ
Matt Wilding

ใช่ฉันกำลังมองไปรอบ ๆ แต่ฉันไม่เห็นมัน เป็นไปได้ว่าพวกเขามุ่งเน้นไปที่พื้นที่ที่ไม่สนับสนุนโดย ObjC เพราะพวกเขาสามารถเติมเต็มช่องว่างเหล่านี้โดยไม่สูญเสียความสามารถมากเกินไป แค่คิดออกมาดัง ๆ :)
โลแกน


3

ฉันรู้ว่ามันเก่าและคำตอบได้รับการยอมรับ แต่คุณสามารถค้นหาดัชนีของสตริงในสองบรรทัดของรหัสโดยใช้:

var str : String = "abcdefghi"
let characterToFind: Character = "c"
let characterIndex = find(str, characterToFind)  //returns 2

ข้อมูลที่ยอดเยี่ยมอื่น ๆ เกี่ยวกับสตริง Swift ที่นี่เงื่อนไขใน Swift


findไม่สามารถใช้ได้ใน Swift 3
AamirR

2

สิ่งนี้ได้ผลสำหรับฉัน

var loc = "abcdefghi".rangeOfString("c").location
NSLog("%d", loc);

มันก็ใช้ได้เช่นกัน

var myRange: NSRange = "abcdefghi".rangeOfString("c")
var loc = myRange.location
NSLog("%d", loc);

ทั้งสองอย่างดูเหมือนจะย้อนกลับไปที่พฤติกรรมของ NSString อย่างใด ในสนามเด็กเล่นของฉันฉันใช้ตัวแปรกลางสำหรับสตริง var str = "abcdef"; str.rangeOfString("c").locationทำให้เกิดข้อผิดพลาดเกี่ยวกับ String.Index ไม่ได้มีการตั้งสมาชิกชื่อ ...
แมตต์ไวล์ดิ้ง

1
มันใช้งานได้เพียงเพราะ "string" เป็น NSString และไม่ใช่ Swift's String
gderaco

2

สตริงชนิดตัวแปรใน Swift มีฟังก์ชันที่แตกต่างเมื่อเปรียบเทียบกับ NSString ใน Objective-C และตามที่ Sulthan พูดถึง

Swift String ไม่ได้ใช้งาน RandomAccessIndex

สิ่งที่คุณสามารถทำได้คือ downcast ตัวแปรประเภทของคุณเป็น NSString (สิ่งนี้ใช้ได้ใน Swift) สิ่งนี้จะทำให้คุณสามารถเข้าถึงฟังก์ชั่นใน NSString

var str = "abcdefghi" as NSString
str.rangeOfString("c").locationx   // returns 2

2

หากคุณคิดเกี่ยวกับสิ่งนี้คุณไม่จำเป็นต้องใช้ตำแหน่ง Int จริงๆ The Range หรือแม้แต่ String.Index ก็เพียงพอที่จะดึงซับสตริงออกได้อีกครั้งหากจำเป็น:

let myString = "hello"

let rangeOfE = myString.rangeOfString("e")

if let rangeOfE = rangeOfE {
    myString.substringWithRange(rangeOfE) // e
    myString[rangeOfE] // e

    // if you do want to create your own range
    // you can keep the index as a String.Index type
    let index = rangeOfE.startIndex
    myString.substringWithRange(Range<String.Index>(start: index, end: advance(index, 1))) // e

    // if you really really need the 
    // Int version of the index:
    let numericIndex = distance(index, advance(index, 1)) // 1 (type Int)
}

คำตอบที่ดีที่สุดสำหรับฉันคือ func indexOf (เป้าหมาย: String) -> Int {return (self as NSString) .rangeOfString (target) .location)
YannSteph

2

วิธีที่ง่ายที่สุดคือ:

ในสวิฟต์ 3 :

 var textViewString:String = "HelloWorld2016"
    guard let index = textViewString.characters.index(of: "W") else { return }
    let mentionPosition = textViewString.distance(from: index, to: textViewString.endIndex)
    print(mentionPosition)

1

สตริงเป็นชนิดบริดจ์สำหรับ NSString ดังนั้นเพิ่ม

import Cocoa

ไปที่ไฟล์ swift ของคุณและใช้วิธี "เก่า" ทั้งหมด


1

ในแง่ของการคิดสิ่งนี้อาจเรียกว่าการบุกรุก คุณค้นพบโลกที่เป็นรอบแทนที่จะแบน "คุณไม่จำเป็นต้องรู้ว่า INDEX ของตัวละครจะทำอะไรกับมัน" และในฐานะโปรแกรมเมอร์ C ฉันก็พบว่ามันยากเหมือนกัน! บรรทัดของคุณ "let index = letters.characters.indexOf (" c ")!" ก็เพียงพอด้วยตัวเอง ตัวอย่างเช่นการลบ c ที่คุณสามารถใช้ ... (paste ในสนามเด็กเล่น)

    var letters = "abcdefg"
  //let index = letters.rangeOfString("c")!.startIndex //is the same as
    let index = letters.characters.indexOf("c")!
    range = letters.characters.indexOf("c")!...letters.characters.indexOf("c")!
    letters.removeRange(range)
    letters

อย่างไรก็ตามหากคุณต้องการดัชนีคุณต้องส่งคืน INDEX จริงไม่ใช่ Int ซึ่งเป็นค่า Int จะต้องมีขั้นตอนเพิ่มเติมสำหรับการใช้งานจริง ส่วนขยายเหล่านี้จะส่งคืนดัชนีจำนวนของอักขระที่เฉพาะเจาะจงและช่วงที่รหัสปลั๊กอินสนามเด็กเล่นนี้จะแสดงให้เห็น

extension String
{
    public func firstIndexOfCharacter(aCharacter: Character) -> String.CharacterView.Index? {

        for index in self.characters.indices {
            if self[index] == aCharacter {
                return index
            }

        }
        return nil
    }

    public func returnCountOfThisCharacterInString(aCharacter: Character) -> Int? {

        var count = 0
        for letters in self.characters{

            if aCharacter == letters{

                count++
            }
        }
        return count
    }


    public func rangeToCharacterFromStart(aCharacter: Character) -> Range<Index>? {

        for index in self.characters.indices {
            if self[index] == aCharacter {
                let range = self.startIndex...index
                return range
            }

        }
        return nil
    }

}



var MyLittleString = "MyVery:important String"

var theIndex = MyLittleString.firstIndexOfCharacter(":")

var countOfColons = MyLittleString.returnCountOfThisCharacterInString(":")

var theCharacterAtIndex:Character = MyLittleString[theIndex!]

var theRange = MyLittleString.rangeToCharacterFromStart(":")
MyLittleString.removeRange(theRange!)

1

โซลูชันที่สมบูรณ์แบบ Swift 4:

OffsetIndexableCollection (สตริงที่ใช้ดัชนี Int)

https://github.com/frogcjn/OffsetIndexableCollection-String-Int-Indexable-

let a = "01234"

print(a[0]) // 0
print(a[0...4]) // 01234
print(a[...]) // 01234

print(a[..<2]) // 01
print(a[...2]) // 012
print(a[2...]) // 234
print(a[2...3]) // 23
print(a[2...2]) // 2

if let number = a.index(of: "1") {
    print(number) // 1
    print(a[number...]) // 1234
}

if let number = a.index(where: { $0 > "1" }) {
    print(number) // 2
}

1

สตริงส่วนขยาย {

//Fucntion to get the index of a particular string
func index(of target: String) -> Int? {
    if let range = self.range(of: target) {
        return characters.distance(from: startIndex, to: range.lowerBound)
    } else {
        return nil
    }
}
//Fucntion to get the last index of occurence of a given string
func lastIndex(of target: String) -> Int? {
    if let range = self.range(of: target, options: .backwards) {
        return characters.distance(from: startIndex, to: range.lowerBound)
    } else {
        return nil
    }
}

}


1

สวิฟท์ 5

ค้นหาดัชนีของสตริงย่อย

let str = "abcdecd"
if let range: Range<String.Index> = str.range(of: "cd") {
    let index: Int = str.distance(from: str.startIndex, to: range.lowerBound)
    print("index: ", index) //index: 2
}
else {
    print("substring not found")
}

ค้นหาดัชนีของตัวละคร

let str = "abcdecd"
if let firstIndex = str.firstIndex(of: "c") {
    let index: Int = str.distance(from: str.startIndex, to: firstIndex)
    print("index: ", index)   //index: 2
}
else {
    print("symbol not found")
}

0

หากคุณกำลังมองหาวิธีที่ง่ายในการรับดัชนีของตัวละครหรือสตริงชำระเงินห้องสมุดนี้http://www.dollarswift.org/#indexof-char-character-int

คุณสามารถรับ indexOf จากสตริงโดยใช้สตริงอื่นเช่นกันหรือรูปแบบ regex


0

วิธีรับดัชนีสตริงย่อยในสตริงด้วย Swift 2:

let text = "abc"
if let range = text.rangeOfString("b") {
   var index: Int = text.startIndex.distanceTo(range.startIndex) 
   ...
}

0

ใน 2.0 ที่รวดเร็ว

var stringMe="Something In this.World"
var needle="."
if let idx = stringMe.characters.indexOf(needle) {
    let pos=stringMe.substringFromIndex(idx)
    print("Found \(needle) at position \(pos)")
}
else {
    print("Not found")
}

0
let mystring:String = "indeep";
let findCharacter:Character = "d";

if (mystring.characters.contains(findCharacter))
{
    let position = mystring.characters.indexOf(findCharacter);
    NSLog("Position of c is \(mystring.startIndex.distanceTo(position!))")

}
else
{
    NSLog("Position of c is not found");
}

0

ฉันเล่นต่อไปนี้

extension String {
    func allCharactes() -> [Character] {
         var result: [Character] = []
         for c in self.characters {
             result.append(c)
         }
         return 
    }
}

จนกว่าฉันจะเข้าใจคนที่ให้มาตอนนี้มันเป็นเพียงตัวละคร

และด้วย

let c = Array(str.characters)

สิ่งนี้ทำให้สำเร็จ โค้ดแรกของคุณดีกว่าบล็อกที่สองอย่างไร
Ben Leggiero

0

หากคุณต้องการเพียงดัชนีของตัวละครวิธีแก้ปัญหาที่ง่ายและรวดเร็วที่สุด (ตามที่ Pascal ได้ชี้ไปแล้ว) คือ:

let index = string.characters.index(of: ".")
let intIndex = string.distance(from: string.startIndex, to: index)

ตัวอักษรถูกคิดค่าเสื่อมราคาในขณะนี้ ... น่าเศร้าแม้ว่าจะได้ผล
ก็ตาม

0

ในเรื่องของการเปลี่ยนที่String.Indexเป็นIntส่วนขยายนี้ทำงานสำหรับฉัน:

public extension Int {
    /// Creates an `Int` from a given index in a given string
    ///
    /// - Parameters:
    ///    - index:  The index to convert to an `Int`
    ///    - string: The string from which `index` came
    init(_ index: String.Index, in string: String) {
        self.init(string.distance(from: string.startIndex, to: index))
    }
}

ตัวอย่างการใช้งานที่เกี่ยวข้องกับคำถามนี้:

var testString = "abcdefg"

Int(testString.range(of: "c")!.lowerBound, in: testString)     // 2

testString = "🇨🇦🇺🇸🇩🇪👩‍👩‍👧‍👦\u{1112}\u{1161}\u{11AB}"

Int(testString.range(of: "🇨🇦🇺🇸🇩🇪")!.lowerBound, in: testString) // 0
Int(testString.range(of: "👩‍👩‍👧‍👦")!.lowerBound, in: testString)    // 1
Int(testString.range(of: "한")!.lowerBound, in: testString)    // 5

สำคัญ:

String.Indexในขณะที่คุณสามารถบอกได้ว่ามันขยายกลุ่มกระจุกตัวอักษรและตัวอักษรเข้าร่วมที่แตกต่างกว่า String.Indexของหลักสูตรนี้คือเหตุผลที่เรามี คุณควรจำไว้ว่าวิธีนี้ถือว่ากลุ่มเป็นอักขระเอกพจน์ซึ่งใกล้จะถูกต้องมากขึ้น หากเป้าหมายของคุณคือการแบ่งสตริงด้วย Unicode codepoint นี่ไม่ใช่วิธีแก้ปัญหาสำหรับคุณ


0

ในSwift 2.0ฟังก์ชันต่อไปนี้จะคืนค่าสตริงย่อยก่อนอักขระที่กำหนด

func substring(before sub: String) -> String {
    if let range = self.rangeOfString(sub),
        let index: Int = self.startIndex.distanceTo(range.startIndex) {
        return sub_range(0, index)
    }
    return ""
}

0

คุณสามารถค้นหาหมายเลขดัชนีของตัวละครในสตริงด้วยสิ่งนี้:

var str = "abcdefghi"
if let index = str.firstIndex(of: "c") {
    let distance = str.distance(from: str.startIndex, to: index)
    // distance is 2
}

0

ในมุมมองของฉันวิธีที่ดีกว่าในการรู้ตรรกะนั้นอยู่ด้านล่าง

 let testStr: String = "I love my family if you Love us to tell us I'm with you"
 var newStr = ""
 let char:Character = "i"

 for value in testStr {
      if value == char {
         newStr = newStr + String(value)
   }

}
print(newStr.count)
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.