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.

Scott Walter
sumber
kemungkinan duplikat panjang String di Swift 1.2 dan Swift 2.0
King-Wizard
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

mginn
sumber
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
Cezar
sumber
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

San
sumber
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)
Whitneyland
sumber
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

Vyacheslav
sumber
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

Kendall Helmstetter Gelner
sumber
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
Scott Gardner
sumber
15

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

var testString = "Scott"
var length = testString.characters.count
Antoine
sumber
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.

Jean Le Moignan
sumber
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"
Saranjith
sumber
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)
Kiet Nguyen
sumber
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)
Jeremy Fox
sumber
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🐶🐶🐶
Tyler Long
sumber
7

Anda bisa mencoba seperti ini

var test1: String = "Scott"
var length =  test1.bridgeToObjectiveC().length
Anil Varghese
sumber
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

Adam
sumber
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)
}
cjd
sumber
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.

VYT
sumber
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
Ashis Laha
sumber
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.

pengguna3812138
sumber
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
kalyan711987
sumber
2

Inilah yang akhirnya saya lakukan

let replacementTextAsDecimal = Double(string)

if string.characters.count > 0 &&
    replacementTextAsDecimal == nil &&
    replacementTextHasDecimalSeparator == nil {
        return false
}
Bryan Clark
sumber
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
Fangming
sumber
2

Cepat 4

let str =  "Your name"

str.count 

Ingat: Ruang juga dihitung dalam angka

Mr.Shin
sumber
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
    }
}
Riajur Rahman
sumber
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

brokenrhino
sumber
1

Cara terbaik untuk menghitung String di Swift adalah ini:

var str = "Hello World"
var length = count(str.utf16)
Zaldy
sumber
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
Tien Dinh
sumber
1
test1.characters.count

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

ex:

test1 = "StackOverflow"

print(test1.characters.count)

( mencetak " 13 ")

Andy Lebowitz
sumber
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.

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