Dapatkan panjang String


780

Bagaimana Anda mendapatkan panjang String? Sebagai contoh, saya memiliki variabel yang didefinisikan seperti:

var test1: String = "Scott"

Namun, sepertinya saya tidak dapat menemukan metode panjang pada string.



Saya harus memigrasi banyak kode secara manual karena Swift 3. Jadi saya memutuskan untuk membuat ekstensi. Jadi sekarang, jika harus meningkatkan ke rilis besar baru, saya hanya perlu memigrasikan ekstensi. Di sini Anda dapat menemukan beberapa ekstensi Swift 3 yang saya buat. github.com/tukur187/Swift3
Shkelzen

Jawaban:


1284

Mulai dari Swift 4+

Hanya saja:

test1.count

karena alasan.

(Terima kasih kepada Martin R)

Mulai dari Swift 2:

Dengan Swift 2, Apple telah mengubah fungsi global menjadi ekstensi protokol, ekstensi yang cocok dengan jenis apa pun yang sesuai dengan protokol. Jadi sintaks baru adalah:

test1.characters.count

(Terima kasih kepada JohnDifool untuk kepala)

Mulai dari Swift 1

Gunakan metode jumlah karakter:

let unusualMenagerie = "Koala 🐨, Snail 🐌, Penguin 🐧, Dromedary 🐪"
println("unusualMenagerie has \(count(unusualMenagerie)) characters")
// prints "unusualMenagerie has 40 characters"

langsung dari Panduan Apple Swift

(perhatikan, untuk versi Swift lebih awal dari 1.2, ini akan menjadi countElements(unusualMenagerie)sebagai gantinya)

untuk variabel Anda, itu akan menjadi

length = count(test1) // was countElements in earlier versions of Swift

Atau Anda dapat menggunakan test1.utf16count


11
Menarik bahwa countElements adalah fungsi global. Apakah ada daftar fungsi global?
Scott Walter

7
Masalahnya dengan countElements adalah ia dinyatakan seperti ini: func countElements <T> (x: T) -> T.IndexType.DistanceType dan tipe kembali tidak menerima operasi +.
MarkAurelius

288
Itu terlalu sulit untuk menambahkan metode str.length. (
Mengangkat

13
Dengan Swift 2, saya hanya bisa menjalankan ini: let len ​​= test1.characters.count
Laurent

7
Perhatikan bahwa dengan Swift 4, itu akan menjadi string.count.
Martin R

335

TLDR:

Untuk Swift 2.0 dan 3.0, gunakan test1.characters.count. Tapi, ada beberapa hal yang harus Anda ketahui. Jadi, baca terus.

Menghitung karakter dalam Swift

Sebelum Swift 2.0, countadalah fungsi global. Pada Swift 2.0, itu bisa disebut sebagai fungsi anggota.

test1.characters.count

Ini akan mengembalikan jumlah sebenarnya dari karakter Unicode dalam String, jadi itu adalah alternatif yang paling benar dalam arti bahwa, jika Anda mencetak string dan menghitung karakter dengan tangan, Anda akan mendapatkan hasil yang sama.

Namun, karena cara Stringsini diterapkan dalam Swift, karakter tidak selalu mengambil jumlah memori yang sama, jadi ketahuilah bahwa ini berperilaku sangat berbeda dari metode penghitungan karakter biasa dalam bahasa lain.

Misalnya, Anda juga bisa menggunakan test1.utf16.count

Tapi, seperti yang tertera di bawah ini, nilai yang dikembalikan tidak dijamin sama dengan yang menelepon countpada characters.

Dari referensi bahasa:

Cluster grapheme diperpanjang dapat terdiri dari satu atau lebih skalar Unicode. Ini berarti bahwa karakter yang berbeda — dan representasi berbeda dari karakter yang sama — dapat membutuhkan jumlah memori yang berbeda untuk disimpan. Karena itu, karakter dalam Swift tidak masing-masing mengambil jumlah memori yang sama dalam representasi string. Akibatnya, jumlah karakter dalam string tidak dapat dihitung tanpa iterasi melalui string untuk menentukan batas cluster grapheme yang diperluas. Jika Anda bekerja dengan nilai-nilai string yang sangat panjang, perlu diketahui bahwa properti karakter harus beralih di atas Unicode skalars di seluruh string untuk menentukan karakter untuk string itu.

Hitungan karakter yang dikembalikan oleh properti karakter tidak selalu sama dengan properti panjang NSString yang berisi karakter yang sama. Panjang NSString didasarkan pada jumlah unit kode 16-bit dalam representasi UTF-16 string dan bukan jumlah cluster grapheme Unicode diperpanjang dalam string.

Contoh yang menggambarkan dengan sempurna situasi yang dijelaskan di atas adalah memeriksa panjang string yang berisi karakter emoji tunggal, seperti yang ditunjukkan oleh n00neimp0rtant dalam komentar.

var emoji = "👍"
emoji.characters.count             //returns 1
emoji.utf16.count                  //returns 2

26
Saya menghargai jawaban Anda yang terperinci dan hati-hati, tetapi saya harus mengakui bahwa itu membuat saya gelisah. Anda memberi saya 3 cara untuk mendapatkan panjang string, semua dengan penafian bahwa jawaban yang mereka berikan mungkin bukan yang Anda harapkan. Apakah benar-benar tidak ada cara yang andal dalam Swift untuk mendapatkan nilai panjang string yang akurat dan andal?
n00neimp0rtant

6
@ n00neimp0rtant. Maaf jika saya tidak menjelaskannya. Solusi pertama ( countElements()) mendapatkan jumlah karakter tepat dalam String. Mungkin berbeda dari apa yang Anda dapatkan dari memanggil [str length]di Objective-C, karena lengthmetode ini mengasumsikan semua karakter dalam string terdiri dari unit kode 16-bit, sambil countElements()mendapatkan jumlah aktual karakter Unicode. Namun, sebagian besar waktu dari semua alternatif di atas akan memberikan hasil yang sama, khususnya jika Anda menggunakan karakter umum bahasa Inggris.
Cezar

2
@ n00neimp0rtant Saya mengubah sedikit jawaban saya untuk mencoba dan membuatnya lebih jelas.
Cezar

2
Saya mengerti maksud Anda sekarang. Saya baru saja mencoba mendapatkan string yang berisi karakter Emoji tunggal; Objective-C memberi saya nilai 4, dan Swift memberi saya nilai 1. Jadi sebenarnya tampak lebih akurat (dan karenanya, ironisnya "tidak seperti yang saya harapkan" = P). Terimakasih atas klarifikasinya!
n00neimp0rtant

1
@ n00neimp0rtant Persis! Itu contoh sempurna. Saya bahkan akan menambahkannya ke jawaban
Cezar

92

Pembaruan Swift 1.2: Tidak ada lagi countElements untuk menghitung ukuran koleksi. Cukup gunakan fungsi hitung sebagai pengganti: hitung ("Swift")

Swift 2.0, 3.0 dan 3.1:

biarkan strLength = string.characters.count

Swift 4.2 (4.0 dan seterusnya): [Apple Documentation - Strings]

biarkan strLength = string.count


61

Swift 1.1

extension String {
    var length: Int { return countElements(self) }  // 
}

Cepat 1.2

extension String {
    var length: Int { return count(self)         }  // 
}

Swift 2.0

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

Cepat 4.2

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

let str = "Hello"
let count = str.length    // returns 5 (Int)

6
Ya, kami membutuhkan lapisan abstraksi untuk sintaks Swift yang berubah setiap bulan!
Cosmin

@Lee Ini tidak berfungsi dalam 4. cepat karena karakter sudah usang. Berlari whac-a-mole terus berlanjut. desah
eonist

48

Cepat 4

"string".count

;)

Cepat 3

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

pemakaian

"string".length


Ini mengembalikan String.CharacterView.IndexDistance. Bagaimana dengan Int?
eonist

@GitSync dimana? Saya tidak mengerti Anda
Vyacheslav

@Vyacheslav di swift 4 "string" .count mengembalikan String.CharacterView.IndexDistance Lihat jawaban saya di sini: stackoverflow.com/a/47203597/5389500 untuk mendapatkan int di swift 3 dan 4
eonist

Saya sudah menguji ini adalah taman bermain:
Vyacheslav

//: Playground - noun: a place where people can play import UIKit var str = "Hello, playground" print(type(of: str.characters.count)) print(type(of: str.count))
Vyacheslav

25

Jika Anda hanya mencoba melihat apakah string kosong atau tidak (memeriksa panjang 0), Swift menawarkan metode uji boolean sederhana pada String

myString.isEmpty

Sisi lain dari koin ini adalah orang-orang bertanya di ObjectiveC bagaimana cara menanyakan apakah string kosong di mana jawabannya adalah untuk memeriksa panjang 0:

NSString kosong


18

tl; dr Jika Anda ingin panjang tipe String dalam hal jumlah karakter yang dapat dibaca manusia, gunakan countElements () . Jika Anda ingin mengetahui panjangnya jumlah kluster grapheme yang diperluas , gunakan endIndex . Baca terus untuk detailnya.

The String jenis diimplementasikan sebagai koleksi memerintahkan (yaitu, urutan) dari karakter Unicode, dan itu sesuai dengan CollectionType protokol, yang sesuai dengan _CollectionType protokol, yang merupakan jenis input yang diharapkan oleh countElements () . Oleh karena itu, countElements () dapat dipanggil, melewati tipe String , dan itu akan mengembalikan jumlah karakter.

Namun, dalam sesuai dengan CollectionType , yang pada gilirannya sesuai dengan _CollectionType , String juga menerapkan startIndex dan endIndex dihitung properti, yang benar-benar mewakili posisi indeks sebelum cluster karakter pertama, dan posisi indeks setelah cluster karakter terakhir, masing-masing . Jadi, dalam string "ABC", posisi indeks sebelum A adalah 0 dan setelah C adalah 3. Oleh karena itu, endIndex = 3, yang juga merupakan panjang dari string.

Jadi, endIndex dapat digunakan untuk mendapatkan panjang semua jenis String, lalu, kan?

Ya, tidak selalu ... Karakter Unicode sebenarnya adalah cluster grapheme yang diperluas , yang merupakan urutan dari satu atau lebih skalar Unicode yang digabungkan untuk membuat satu karakter yang dapat dibaca manusia.

let circledStar: Character = "\u{2606}\u{20DD}" // ☆⃝

circledStar adalah karakter tunggal yang terdiri dari U + 2606 (bintang putih), dan U + 20DD (lingkaran penutup yang menggabungkan). Mari kita membuat String dari circledStar dan membandingkan hasil countElements () dan endIndex .

let circledStarString = "\(circledStar)"
countElements(circledStarString) // 1
circledStarString.endIndex // 2

15

Di Swift 2.0 counttidak berfungsi lagi. Anda bisa menggunakan ini sebagai gantinya:

var testString = "Scott"
var length = testString.characters.count

14

Berikut ini sesuatu yang lebih pendek, dan lebih alami daripada menggunakan fungsi global:

aString.utf16count

Saya tidak tahu apakah itu tersedia dalam versi beta 1. Tapi itu pasti ada di beta 2.


2
Lihat jawaban Cezar. Ini tidak selalu memberi Anda jumlah "karakter" dalam string, untuk definisi "karakter" kebanyakan orang. Kemudian lagi, begitu pula Objective-C - terserah Anda untuk memutuskan apakah Anda peduli atau tidak.
jbg

12

Swift 5.1, 5

let flag = "🇵🇷"

print(flag.count)
// Prints "1" --  Counts the characters and emoji as length 1

print(flag.unicodeScalars.count)
// Prints "2" --  Counts the unicode lenght ex. "A" is 65

print(flag.utf16.count)
// Prints "4"

print(flag.utf8.count)
// Prints "8"

11

Diperbarui untuk Xcode 6 beta 4, ubah metode utf16count -> utf16Count

 var test1: String = "Scott"
 var length =  test1.utf16Count

Atau

 var test1: String = "Scott"
 var length = test1.lengthOfBytesUsingEncoding(NSUTF16StringEncoding)

Saat Anda menggunakan string kompleks dengan emoji, jawabannya dengan utf16countakan salah
Victor Sigler

10

Pada Swift 1.2 utf16Counttelah dihapus. Anda sekarang harus menggunakan count()fungsi global dan meneruskan tampilan string UTF16. Contoh di bawah ini ...

let string = "Some string"
count(string.utf16)

1
Apakah lebih lambat dari .utf16count?
samir105

1
Tampaknya kecepatan yang sama dengan .utf16count, jauh lebih cepat dari hitungan (string)
samir105

8

Untuk Xcode 7.3 dan Swift 2.2.

let str = "🐶"
  1. Jika Anda ingin jumlah karakter visual:

    str.characters.count
  2. Jika Anda ingin "unit kode 16-bit dalam representasi UTF-16 string":

    str.utf16.count

Sebagian besar waktu, 1 adalah apa yang Anda butuhkan.

Kapan Anda membutuhkan 2 ? Saya telah menemukan use case untuk 2 :

let regex = try! NSRegularExpression(pattern:"🐶", 
    options: NSRegularExpressionOptions.UseUnixLineSeparators)
let str = "🐶🐶🐶🐶🐶🐶"
let result = regex.stringByReplacingMatchesInString(str, 
    options: NSMatchingOptions.WithTransparentBounds, 
    range: NSMakeRange(0, str.utf16.count), withTemplate: "dog")
print(result) // dogdogdogdogdogdog

Jika Anda menggunakan 1 , hasilnya salah:

let result = regex.stringByReplacingMatchesInString(str, 
    options: NSMatchingOptions.WithTransparentBounds, 
    range: NSMakeRange(0, str.characters.count), withTemplate: "dog")
print(result) // dogdogdog🐶🐶🐶

7

Anda bisa mencoba seperti ini

var test1: String = "Scott"
var length =  test1.bridgeToObjectiveC().length

4
Itu sama dengantest1.utf16count
Sulthan

1
@vladof well, itu "semacam" bekerja. Lihat jawaban Cezar.
jbg

6

di Swift 2.x berikut ini adalah cara menemukan panjang string

let findLength = "This is a string of text"
findLength.characters.count

mengembalikan 24


5

Swift 2.0: Dapatkan penghitungan: yourString.text.characters.count

Contoh menyenangkan tentang bagaimana ini berguna adalah untuk menunjukkan hitung mundur karakter dari beberapa nomor (misalnya 150) dalam UITextView:

func textViewDidChange(textView: UITextView) {
    yourStringLabel.text = String(150 - yourStringTextView.text.characters.count)
}

4

Di swift4 saya selalu menggunakan string.countsampai hari ini saya telah menemukan itu

string.endIndex.encodedOffset

adalah substitusi yang lebih baik karena lebih cepat - untuk 50.000 karakter string adalah sekitar 6 kali lebih cepat daripada .count. The .counttergantung pada panjang string tetapi.endIndex.encodedOffset tidak.

Tetapi ada satu TIDAK. Ini tidak baik untuk string dengan emoji, itu akan memberikan hasil yang salah, jadi hanya .countbenar.


3

Dalam Swift 4 : Jika string tidak mengandung karakter unicode, gunakan yang berikut ini

let str : String = "abcd"
let count = str.count // output 4

Jika string berisi karakter unicode maka gunakan berikut ini:

let spain = "España"
let count1 = spain.count // output 6
let count2 = spain.utf8.count // output 7

Mengapa Anda ingin menggunakannya utf8.count? Itu tidak memberikan hitungan karakter. Ini memberikan jumlah byte yang dibutuhkan untuk pengkodean string UTF-8.
rmaddy

2

Dalam Xcode 6.1.1

extension String {    
    var length : Int { return self.utf16Count  }
}

Saya pikir para Jenius akan mengubah ini pada setiap versi minor.


2

Dapatkan nilai string dari tampilan teks atau bidang teks Anda:

let textlengthstring = (yourtextview?.text)! as String

Temukan jumlah karakter dalam string:

let numberOfChars = textlength.characters.count

2

Inilah yang akhirnya saya lakukan

let replacementTextAsDecimal = Double(string)

if string.characters.count > 0 &&
    replacementTextAsDecimal == nil &&
    replacementTextHasDecimalSeparator == nil {
        return false
}

Saya pikir Anda mencoba melakukan lebih dari sekadar mendapatkan panjang tali, dan dalam hal apa pun ini terlihat tidak lengkap (bukankah seharusnya ada return truekasing?). Bisakah Anda mengecek ulang dan, kalau-kalau, edit jawaban Anda? Terima kasih!
Fabio mengatakan Reinstate Monica

2

Pembaruan Swift 4 membandingkan dengan swift 3

Swift 4 menghilangkan kebutuhan akan array karakter pada String. Ini berarti bahwa Anda dapat langsung memanggil countstring tanpa terlebih dahulu mendapatkan karakter array.

"hello".count                  // 5

Sedangkan di swift 3, Anda harus mendapatkan karakter array dan kemudian menghitung elemen dalam array itu. Perhatikan bahwa metode berikut ini masih tersedia di swift 4.0 karena Anda masih dapat memanggil charactersuntuk mengakses array karakter dari string yang diberikan

"hello".characters.count       // 5

Swift 4.0 juga mengadopsi Unicode 9 dan sekarang dapat menginterpretasikan cluster grapheme. Misalnya, mengandalkan emoji akan memberi Anda 1 saat di swift 3.0, Anda mungkin mendapatkan jumlah lebih dari 1.

"👍🏽".count // Swift 4.0 prints 1, Swift 3.0 prints 2
"👨‍❤️‍💋‍👨".count // Swift 4.0 prints 1, Swift 3.0 prints 4

2

Cepat 4

let str =  "Your name"

str.count 

Ingat: Ruang juga dihitung dalam angka


2

Anda bisa mendapatkan panjangnya hanya dengan menulis ekstensi:

extension String {
    // MARK: Use if it's Swift 2
    func stringLength(str: String) -> Int {
        return str.characters.count
    }

    // MARK: Use if it's Swift 3
    func stringLength(_ str: String) -> Int {
        return str.characters.count
    }

    // MARK: Use if it's Swift 4
    func stringLength(_ str: String) -> Int {
        return str.count
    }
}

1
var str = "Hello, playground"
var newString = str as NSString    

countElements(str)

Ini menghitung karakter dalam String Swift Biasa

countElements((newString as String))    

Ini menghitung karakter dalam NSString


1

Cara terbaik untuk menghitung String di Swift adalah ini:

var str = "Hello World"
var length = count(str.utf16)

2
Anda harus menggunakan hanya menghitung (str). Coba kamu gunakan count (str.utf16) dengan sub string advance ()
Leo Dabus

1

String dan NSString adalah jembatan bebas pulsa sehingga Anda dapat menggunakan semua metode yang tersedia untuk NSString dengan String cepat

let x = "test" as NSString
let y : NSString = "string 2"
let lenx = x.count
let leny = y.count

1
test1.characters.count

akan memberi Anda jumlah huruf / angka dll di string Anda.

ex:

test1 = "StackOverflow"

print(test1.characters.count)

( mencetak " 13 ")


1

Apple membuatnya berbeda dari bahasa utama lainnya. Cara saat ini adalah menelepon:

test1.characters.count

Namun, untuk berhati-hati, ketika Anda mengatakan panjang Anda berarti jumlah karakter bukan jumlah byte, karena keduanya dapat berbeda ketika Anda menggunakan karakter non-ascii.

Sebagai contoh; "你好啊hi".characters.countakan memberi Anda 5 tetapi ini bukan hitungan byte. Untuk mendapatkan jumlah byte yang sebenarnya, Anda perlu melakukannya "你好啊hi".lengthOfBytes(using: String.Encoding.utf8). Ini akan memberi Anda 11.


1

Saat ini (dalam Swift 2.3) jika Anda menggunakan:

myString.characters.count 

metode akan mengembalikan tipe "Jarak", jika Anda membutuhkan metode untuk mengembalikan Integer Anda harus mengetikkan cor seperti:

var count = myString.characters.count as Int

2
The Distancedari String.CharacterView ini Int , seharusnya tidak ada kebutuhan untuk cor ini.
Martin R
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.