Bagaimana saya bisa menggunakan subscript pengiris String di Swift 4?


294

Saya memiliki kode sederhana berikut yang ditulis dalam Swift 3:

let str = "Hello, playground"
let index = str.index(of: ",")!
let newStr = str.substring(to: index)

Dari Xcode 9 beta 5, saya mendapatkan peringatan berikut:

' substring(to:)' sudah usang: Silakan gunakan Stringslicing subscript dengan operator 'rentang sebagian dari'.

Bagaimana subskrip pengiris ini dengan rentang sebagian dapat digunakan di Swift 4?


var str = "Halo, taman bermain" biarkan indexcut = str.firstIndex (dari: ",") mencetak (String (str [.. <indexcut!])) print (String (str [indexcut! ...]))
user1828845

Jawaban:


375

Anda harus membiarkan satu sisi kosong , karenanya nama "rentang parsial".

let newStr = str[..<index]

Kepanjangan yang sama untuk rentang parsial dari operator, biarkan sisi lain kosong:

let newStr = str[index...]

Perlu diingat bahwa operator jangkauan ini mengembalikan a Substring. Jika Anda ingin mengubahnya menjadi string, gunakan Stringfungsi inisialisasi:

let newStr = String(str[..<index])

Anda dapat membaca lebih lanjut tentang substring baru di sini .


8
str[..<index]mengembalikan a Substring. Jika Anda ingin newStrmenjadi seorang StringAnda harus menulis:let newStr = "\(str[..<index])"
Lindemann

12
Menggunakan interpolasi string dengan tunggal Substringmungkin sedikit membingungkan, karena apa yang Anda benar-benar capai adalah Stringinisialisasi: let newStr = String(str[..<index]).
Gary

5
Memperbarui kode di mana nilai 'indeks' saya hanyalah bilangan bulat yang menghasilkan pesan kesalahan Cannot subscript a value of type 'String' with an index of type 'PartialRangeUpTo<Int>',. Jenis nilai apa yang harus digunakan di sana?
ConfusionTowers

22
@ConfusionTowers, indeks string Swift bukan bilangan bulat , dan itu tidak berubah dengan versi 4. Anda mungkin perlu str[..<str.index(str.startIndex, offsetBy: 8)]atau sesuatu seperti itu. Ingatlah bahwa itu str.indexadalah operasi linear-waktu dalam fungsi offsetBy.
zneak

6
@zneak Anda mungkin inginstr.prefix(8)
Tim Vermeulen

264

Konversi Substring (Swift 3) ke String Slicing (Swift 4)

Contoh dalam Swift 3, 4:

let newStr = str.substring(to: index) // Swift 3
let newStr = String(str[..<index]) // Swift 4

let newStr = str.substring(from: index) // Swift 3
let newStr = String(str[index...]) // Swift 4 

let range = firstIndex..<secondIndex // If you have a range
let newStr = = str.substring(with: range) // Swift 3
let newStr = String(str[range])  // Swift 4

5
Perfecto, dan terima kasih telah memberikan 3 dan 4 contoh secara berdampingan, membuat memperbarui proyek saya lebih mudah!
Ethan Parker

86

Cepat 5, 4

Pemakaian

let text = "Hello world"
text[0] // H
text[...3] // "Hell"
text[6..<text.count] // world
text[NSRange(location: 6, length: 3)] // wor

Kode

import Foundation

public extension String {
  subscript(value: Int) -> Character {
    self[index(at: value)]
  }
}

public extension String {
  subscript(value: NSRange) -> Substring {
    self[value.lowerBound..<value.upperBound]
  }
}

public extension String {
  subscript(value: CountableClosedRange<Int>) -> Substring {
    self[index(at: value.lowerBound)...index(at: value.upperBound)]
  }

  subscript(value: CountableRange<Int>) -> Substring {
    self[index(at: value.lowerBound)..<index(at: value.upperBound)]
  }

  subscript(value: PartialRangeUpTo<Int>) -> Substring {
    self[..<index(at: value.upperBound)]
  }

  subscript(value: PartialRangeThrough<Int>) -> Substring {
    self[...index(at: value.upperBound)]
  }

  subscript(value: PartialRangeFrom<Int>) -> Substring {
    self[index(at: value.lowerBound)...]
  }
}

private extension String {
  func index(at offset: Int) -> String.Index {
    index(startIndex, offsetBy: offset)
  }
}

14
fungsi ini harus menjadi perilaku cepat default.
Laimis

4
Jelas PR ini ke Swift lib: D
OhadM

2
Ini adalah perbaikan dari bagian terjelek dari Swift.
Dmitry

@Lakukan seseorang tidak menyukainya, karena jawaban ini memiliki -2. : D
dimpiax

Ini adalah jawaban yang buruk karena operator subscript menyembunyikan O (n) kompleksitas dari fungsi indeks. API pemrograman yang baik hanya menggunakan subskrip untuk menunjukkan pencarian cepat.
ragnarius

38

Lebih pendek dalam Swift 4/5:

var string = "123456"
string = String(string.prefix(3)) //"123"
string = String(string.suffix(3)) //"456"

26

Konversi kode Anda ke Swift 4 juga dapat dilakukan dengan cara ini:

let str = "Hello, playground"
let index = str.index(of: ",")!
let substr = str.prefix(upTo: index)

Anda dapat menggunakan kode di bawah ini untuk memiliki string baru:

let newString = String(str.prefix(upTo: index))

17

substring (from: index) Dikonversi ke [indeks ...]

Periksa sampel

let text = "1234567890"
let index = text.index(text.startIndex, offsetBy: 3)

text.substring(from: index) // "4567890"   [Swift 3]
String(text[index...])      // "4567890"   [Swift 4]

1
karakter sudah usang dalam Swift 4, saya pikir Anda harus mengubah contoh untuk mendapatkan indeks untuk Swift 4
AbuTaareq

Ini membantu saya. tnx
user1105951

17

Swift5

(Metode substring Java):

extension String {
    func subString(from: Int, to: Int) -> String {
       let startIndex = self.index(self.startIndex, offsetBy: from)
       let endIndex = self.index(self.startIndex, offsetBy: to)
       return String(self[startIndex...endIndex])
    }
}

Pemakaian:

var str = "Hello, Nick Michaels"
print(str.subString(from:7,to:20))
// print Nick Michaels

2
Masih berfungsi di Swift 5. Saya mencari substring gaya Java ( fromuntuk to-1, misalnya "Hello".substring(1,4)mengembalikan "ell"). Dengan modifikasi kecil ( startIndex..<endIndex) ini adalah solusi terbaik yang saya temukan sejauh ini yang tidak persis hanya dengan beberapa baris kode.
Neph

9

Beberapa ekstensi bermanfaat:

extension String {
    func substring(from: Int, to: Int) -> String {
        let start = index(startIndex, offsetBy: from)
        let end = index(start, offsetBy: to - from)
        return String(self[start ..< end])
    }

    func substring(range: NSRange) -> String {
        return substring(from: range.lowerBound, to: range.upperBound)
    }
}

Menarik, saya memikirkan hal yang sama. Apakah String (baris ["http: //" .endIndex ...]) lebih jelas daripada substring yang sudah usang? line.substring (dari: "http: //" .endIndex) mungkin sampai mereka mendapatkan tujuan yang dinyatakan dari penanganan string yang luar biasa, mereka tidak boleh mencela substring.
possen

7

Contoh uppercasedFirstCharacterproperti praktis di Swift3 dan Swift4.

Properti uppercasedFirstCharacterNewmendemonstrasikan cara menggunakan subscript String slicing di Swift4.

extension String {

   public var uppercasedFirstCharacterOld: String {
      if characters.count > 0 {
         let splitIndex = index(after: startIndex)
         let firstCharacter = substring(to: splitIndex).uppercased()
         let sentence = substring(from: splitIndex)
         return firstCharacter + sentence
      } else {
         return self
      }
   }

   public var uppercasedFirstCharacterNew: String {
      if characters.count > 0 {
         let splitIndex = index(after: startIndex)
         let firstCharacter = self[..<splitIndex].uppercased()
         let sentence = self[splitIndex...]
         return firstCharacter + sentence
      } else {
         return self
      }
   }
}

let lorem = "lorem".uppercasedFirstCharacterOld
print(lorem) // Prints "Lorem"

let ipsum = "ipsum".uppercasedFirstCharacterNew
print(ipsum) // Prints "Ipsum"

1
Jika yang Anda maksud substring (with: range) -> self [range]
Arsen Vartbaronov

6

Anda dapat membuat metode subString khusus menggunakan ekstensi ke String kelas seperti di bawah ini:

extension String {
    func subString(startIndex: Int, endIndex: Int) -> String {
        let end = (endIndex - self.count) + 1
        let indexStartOfText = self.index(self.startIndex, offsetBy: startIndex)
        let indexEndOfText = self.index(self.endIndex, offsetBy: end)
        let substring = self[indexStartOfText..<indexEndOfText]
        return String(substring)
    }
}

Jika ini akan mengambil endIndex, itu harus mampu menangani di luar batas juga.
Jay

5

Membuat SubString (awalan dan akhiran) dari String menggunakan Swift 4:

let str : String = "ilike"
for i in 0...str.count {
    let index = str.index(str.startIndex, offsetBy: i) // String.Index
    let prefix = str[..<index] // String.SubSequence
    let suffix = str[index...] // String.SubSequence
    print("prefix \(prefix), suffix : \(suffix)")
}

Keluaran

prefix , suffix : ilike
prefix i, suffix : like
prefix il, suffix : ike
prefix ili, suffix : ke
prefix ilik, suffix : e
prefix ilike, suffix : 

Jika Anda ingin membuat substring antara 2 indeks, gunakan:

let substring1 = string[startIndex...endIndex] // including endIndex
let subString2 = string[startIndex..<endIndex] // excluding endIndex

biarkan awalan = str [... <index>] alih-alih str [.. <index>] satu titik tidak ada.
AbuTaareq

@AbuTaareq, yang mana yang Anda bicarakan? biarkan awalan = str [.. <indeks], itu sempurna. (string awalan). Coba mainkan untuk mendapatkan lebih banyak konteks.
Ashis Laha

4

Saya telah menulis ekstensi string untuk penggantian 'String: subString:'

extension String {
    
    func sliceByCharacter(from: Character, to: Character) -> String? {
        let fromIndex = self.index(self.index(of: from)!, offsetBy: 1)
        let toIndex = self.index(self.index(of: to)!, offsetBy: -1)
        return String(self[fromIndex...toIndex])
    }
    
    func sliceByString(from:String, to:String) -> String? {
        //From - startIndex
        var range = self.range(of: from)
        let subString = String(self[range!.upperBound...])
        
        //To - endIndex
        range = subString.range(of: to)
        return String(subString[..<range!.lowerBound])
    }
    
}

Penggunaan: "Date(1511508780012+0530)".sliceByString(from: "(", to: "+")

Contoh Hasil : "1511508780012"

PS: Opsional dipaksa untuk membuka. Silakan tambahkan Jenis pemeriksaan keamanan bila perlu.


Perhatian: opsional dipaksa untuk dibuka. silakan tambahkan Jenis pemeriksaan keamanan jika perlu.
Janeevan

3

Saat pemrograman saya sering memiliki string hanya dengan A-Za-z dan 0-9. Tidak perlu untuk tindakan Indeks yang sulit. Ekstensi ini didasarkan pada fungsi kiri / tengah / kanan tua polos.

extension String {

    // LEFT
    // Returns the specified number of chars from the left of the string
    // let str = "Hello"
    // print(str.left(3))         // Hel
    func left(_ to: Int) -> String {
        return "\(self[..<self.index(startIndex, offsetBy: to)])"
    }

    // RIGHT
    // Returns the specified number of chars from the right of the string
    // let str = "Hello"
    // print(str.left(3))         // llo
    func right(_ from: Int) -> String {
        return "\(self[self.index(startIndex, offsetBy: self.length-from)...])"
    }

    // MID
    // Returns the specified number of chars from the startpoint of the string
    // let str = "Hello"
    // print(str.left(2,amount: 2))         // ll
    func mid(_ from: Int, amount: Int) -> String {
        let x = "\(self[self.index(startIndex, offsetBy: from)...])"
        return x.left(amount)
    }
}

Ide yang hebat!! Sedih bahwa ada kebutuhan untuk abstrak fitur Swift hanya karena mereka terus-menerus mengubah cara kerja. Kira mereka ingin kita semua fokus pada konstruksi daripada produktivitas. Ngomong-ngomong, saya membuat beberapa pembaruan kecil pada kode bagus Anda: pastebin.com/ManWmNnW
Fredrik Johansson

2

dengan metode ini Anda bisa mendapatkan rentang string tertentu. Anda harus melewati indeks mulai dan setelah jumlah karakter yang Anda inginkan.

extension String{
    func substring(fromIndex : Int,count : Int) -> String{
        let startIndex = self.index(self.startIndex, offsetBy: fromIndex)
        let endIndex = self.index(self.startIndex, offsetBy: fromIndex + count)
        let range = startIndex..<endIndex
        return String(self[range])
    }
}

2

Ini solusi saya, tidak ada peringatan, tidak ada kesalahan, tetapi sempurna

let redStr: String = String(trimmStr[String.Index.init(encodedOffset: 0)..<String.Index.init(encodedOffset: 2)])
let greenStr: String = String(trimmStr[String.Index.init(encodedOffset: 3)..<String.Index.init(encodedOffset: 4)])
let blueStr: String = String(trimmStr[String.Index.init(encodedOffset: 5)..<String.Index.init(encodedOffset: 6)])

Penggunaan encodedOffsetyang dianggap berbahaya dan akan ditinggalkan .
Martin R

1

Semoga ini sedikit membantu: -

var string = "123456789"

Jika Anda ingin substring setelah beberapa indeks tertentu.

var indexStart  =  string.index(after: string.startIndex )// you can use any index in place of startIndex
var strIndexStart   = String (string[indexStart...])//23456789

Jika Anda menginginkan substring setelah melepas beberapa string di bagian akhir.

var indexEnd  =  string.index(before: string.endIndex)
var strIndexEnd   = String (string[..<indexEnd])//12345678

Anda juga dapat membuat indeks dengan kode berikut: -

var  indexWithOffset =  string.index(string.startIndex, offsetBy: 4)

0

Semoga bermanfaat.

extension String {
    func getSubString(_ char: Character) -> String {
        var subString = ""
        for eachChar in self {
            if eachChar == char {
                return subString
            } else {
                subString += String(eachChar)
            }
        }
        return subString
    }
}


let str: String = "Hello, playground"
print(str.getSubString(","))

0
var str = "Hello, playground"
let indexcut = str.firstIndex(of: ",")
print(String(str[..<indexcut!]))
print(String(str[indexcut!...]))

Anda dapat mencoba dengan cara ini dan akan mendapatkan hasil yang tepat.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.