Dizenin uzunluğunu al


781

A'nın uzunluğunu nasıl elde edersiniz String? Örneğin, şöyle tanımlanmış bir değişken var:

var test1: String = "Scott"

Ancak, dizede bir uzunluk yöntemi bulamıyorum.



Swift 3 yüzünden çok sayıda kodu manuel olarak taşımak zorunda kaldım. Bu yüzden uzantılar oluşturmaya karar verdim. Şimdi, yeni bir büyük sürüme yükseltmek zorunda kalırsam, sadece uzantıyı taşımam gerekiyor. Burada oluşturduğum bazı Swift 3 uzantılarını bulabilirsiniz. github.com/tukur187/Swift3
Şkelzen

Yanıtlar:


1284

Swift 4+ itibariyle

Bu sadece:

test1.count

nedenlerle.

(Martin R sayesinde)

Swift 2'den itibaren:

Swift 2 ile Apple, global işlevleri protokol uzantılarına, bir protokole uyan her türle eşleşen uzantılara değiştirdi. Böylece yeni sözdizimi:

test1.characters.count

(JohnDifool'a başkanlık için teşekkürler)

Swift itibariyle 1

Sayı karakterleri yöntemini kullanın:

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

doğrudan Apple Swift Kılavuzu'ndan

(not, Swift'in 1.2'den önceki sürümleri için, countElements(unusualMenagerie)bunun yerine)

değişkeniniz için

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

Veya test1.utf16count kullanabilirsiniz


11
İlginçtir countElements küresel bir işlevdir. Global fonksiyonların bir listesi var mı?
Scott Walter

7
CountElements ile ilgili sorun şudur: func countElements <T> (x: T) -> T.IndexType.DistanceType ve return türü + işlemini kabul etmiyor.
MarkAurelius

288
Bir str.length yöntemi eklemek çok zordu. (öfkesinde yumruğunu yükseltir)
botbot

13
Swift 2 ile, sadece bunu işe alabilirim: let len ​​= test1.characters.count
Laurent

7
Swift 4 ile bunun olacağını unutmayın string.count.
Martin R

335

TLDR:

İçin Swift 2.0 ve 3.0, kullanım test1.characters.count. Ancak bilmeniz gereken birkaç şey var. Yani, okumaya devam edin.

Swift'te karakter sayma

Swift 2.0'dan önce countküresel bir işlevdi. Swift 2.0'dan itibaren üye işlevi olarak adlandırılabilir.

test1.characters.count

Gerçek Unicode karakter sayısını a döndürür String, bu nedenle dizeyi yazdırır ve karakterleri el ile sayarsanız aynı sonucu elde etmeniz açısından en doğru alternatif budur.

Bununla birlikte, StringsSwift'te uygulanma şekli nedeniyle , karakterler her zaman aynı miktarda bellek kullanmazlar, bu yüzden bunun diğer dillerdeki normal karakter sayısı yöntemlerinden oldukça farklı davrandığını unutmayın.

Örneğin, test1.utf16.count

Aşağıda belirtildiği gibi,, döndürülen değer çağıran aynı olması garanti edilmez countüzerinde characters.

Dil referansından:

Genişletilmiş grafik kümeleri, bir veya daha fazla Unicode skalerden oluşabilir. Bu, farklı karakterlerin ve aynı karakterin farklı sunumlarının depolanması için farklı miktarlarda bellek gerektirebileceği anlamına gelir. Bu nedenle, Swift'teki karakterlerin her biri, bir dizenin temsili içinde aynı miktarda bellek almaz. Sonuç olarak, bir dizedeki karakter sayısı, genişletilmiş grafik küme sınırlarını belirlemek için dize yinelemeden hesaplanamaz. Özellikle uzun dize değerleriyle çalışıyorsanız, o dizenin karakterlerini belirlemek için characters özelliğinin tüm dize içindeki Unicode skalerlerini yinelemesi gerektiğini unutmayın.

Characters özelliği tarafından döndürülen karakterlerin sayısı, her zaman aynı karakterleri içeren bir NSString öğesinin length özelliğiyle aynı değildir. NSString'in uzunluğu, dizenin içindeki Unicode genişletilmiş grafik kümelerinin sayısını değil, dizenin UTF-16 gösterimi içindeki 16 bit kod birimlerinin sayısını temel alır.

Yukarıda açıklanan durumu mükemmel bir şekilde gösteren bir örnek , yorumlarda n00neimp0rtant tarafından işaret edildiği gibi, tek bir emoji karakteri içeren bir dizenin uzunluğunu kontrol etmektir .

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

26
Ayrıntılı ve tedbirli cevabınızı takdir ediyorum, ancak itiraf etmeliyim ki beni huzursuz bıraktı. Bana bir ipin uzunluğunu almanın 3 yolunu verdiniz, hepsi de verdikleri cevapların beklediğiniz gibi olmayabileceği reddi ile. Bir dizginin doğru, güvenilir bir uzunluk değerini elde etmek için Swift'te gerçekten güvenilir bir yol yok mu?
n00neimp0rtant

6
@ n00neimp0rtant. Eğer netleştirmediysem özür dilerim. İlk çözüm ( countElements()) Dize'deki tam karakter sayısını alır. Gerçekte Unicode karakter sayısını alırken [str length], lengthyöntem dizedeki tüm karakterlerin 16 bit kod birimlerinden oluştuğunu varsayacağından , Objective-C'de çağırmanızdan farklı olabilir countElements(). Ancak, çoğu zaman yukarıdaki alternatiflerin tümü, özellikle İngilizce ortak karakterlerle çalışıyorsanız, aynı sonuçları döndürür.
Cezar

2
@ n00neimp0rtant Cevabımı biraz daha düzeltmeye çalıştım ve daha net hale getirdim.
Cezar

2
Ne demek istediğini şimdi anlıyorum. Sadece tek bir Emoji karakteri içeren bir dizenin uzunluğunu elde etmeye çalıştım; Objective-C bana 4 değerini verdi ve Swift bana 1 değerini verdi. Bu yüzden aslında daha doğru görünüyor (ve dolayısıyla ironik olarak "beklediğim gibi değil" = P). Açıklama için teşekkürler!
n00neimp0rtant

1
@ n00neimp0rtant Kesinlikle! Bu mükemmel bir örnek. Hatta cevaba ekleyeceğim
Cezar

92

Swift 1.2 Güncellemesi: Artık koleksiyonların sayısını saymak için bir countElements yok. Sadece sayma işlevini yedek olarak kullanın: count ("Swift")

Swift 2.0, 3.0 ve 3.1:

let strLength = string.characters.count

Swift 4.2 (4.0 sonrası): [Apple Belgeleri - Dizeler]

let strLength = string.count


61

Hızlı 1.1

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

Hızlı 1.2

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

Swift 2.0

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

Hızlı 4.2

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

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

6
Evet, Swift'in sözdizimi için aylık olarak değişen bir soyutlama katmanına ihtiyacımız var!
Cosmin

@Lee Karakterler kullanımdan kaldırıldığı için bu işlem hızlı bir şekilde 4. çalışmaz. Köstebek whac-a-köstebek devam ediyor. iç
çekiyor

48

Hızlı 4

"string".count

;)

Hızlı 3

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

kullanım

"string".length


String.CharacterView.IndexDistance döndürür. Int ne olacak?
eonist

@GitSync nerede? Seni anlamıyorum
Vyacheslav

@Vyacheslav hızlı 4 "dize". Sayının döndürülmesi String.CharacterView.IndexDistance Burada cevabımı görün: stackoverflow.com/a/47203597/5389500 hızlı 3 ve 4'te int almak için
eonist

Bu oyun alanı test ettim:
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

Bir dizenin boş olup olmadığını görmeye çalışıyorsanız (0 uzunluğunu kontrol edin), Swift basit bir boole testi yöntemi sunar. String

myString.isEmpty

Bu madalyonun diğer tarafı, ObjectiveC'de cevabın 0 olup olmadığını kontrol etmek için nerede bir dize boş olup olmadığını nasıl soracağını soran insanlardı:

NSString boş


18

tl; dr Bir String türünün insan tarafından okunabilir karakter sayısı olarak uzunluğunu istiyorsanız countElements () kullanın . Uzunluğu, genişletilmiş grafik kümeleri sayısı olarak bilmek istiyorsanız endIndex kullanın . Ayrıntılar için okumaya devam edin.

Yaylı türü sıralı bir toplama Unicode karakterleri (yani, dizi) olarak uygulanır ve bu uygun CollectionType protokolü, hangi uygundur _CollectionType beklenen giriş türüdür protokol countElements () . Bu nedenle, bir String türünü geçerek countElements () çağrılabilir ve karakter sayısını döndürür.

Ancak uymakta CollectionType için dönüş uygun olup içinde, _CollectionType , Dize de uygular startIndex ve endIndex aslında endeksi pozisyonunu temsil bilgisayarlı özelliklerini, önce ilk karakter kümesi ve dizinin pozisyonunda sonra , son karakter kümesi sırasıyla . Yani, "ABC" dizesinde, dizinin A'dan önceki konumu 0 ve C'den sonra 3'tür. Bu nedenle, dizenin uzunluğu olan endIndex = 3.

Yani, endIndex herhangi bir String türünün uzunluğunu elde etmek için kullanılabilir, değil mi?

Her zaman değil ... Unicode karakterler aslında tek bir insan tarafından okunabilir karakter oluşturmak için bir veya daha fazla Unicode skalerinin dizisi olan genişletilmiş grafik kümeleridir .

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

circledStar , U + 2606 (beyaz bir yıldız) ve U + 20DD'den (birleşik bir çevreleyen daire) oluşan tek bir karakterdir. Diyelim bir oluşturmak Dize gelen circledStar ve sonuçlarını karşılaştırmak countElements () ve endIndex .

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

15

Swift 2.0'da countartık çalışmıyor. Bunun yerine şunları kullanabilirsiniz:

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

14

İşte küresel bir işlevi kullanmaktan daha kısa ve daha doğal bir şey:

aString.utf16count

Yine de beta 1'de mevcut olup olmadığını bilmiyorum. Ama beta 2'de kesinlikle var.


2
Cezar'ın cevabına bakınız. Bu, çoğu insanın “karakter” tanımlaması için size dizedeki “karakter” sayısını vermez. Daha sonra tekrar, Objective-C de yapmadı - umursayıp ummadığınıza karar vermek size kalmış.
jbg

12

Hızlı 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

Xcode 6 beta 4 için güncellendi, utf16count yöntemini değiştirin -> utf16Count

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

Veya

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

Emoji ile karmaşık dizeler kullandığınızda, bunun yanıtı utf16countyanlış olacaktır
Victor Sigler

10

Swift 1.2 utf16Countitibariyle kaldırıldı. Şimdi global count()işlevi kullanmalı ve dizenin UTF16 görünümünü geçirmelisiniz. Aşağıdaki örnek ...

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

1
.Utf16count'dan daha yavaş mı?
samir105

1
.Utf16count ile aynı hızda görünüyor, sayımdan çok daha hızlı (string)
samir105

8

Xcode 7.3 ve Swift 2.2 için.

let str = "🐶"
  1. Görsel karakter sayısını istiyorsanız:

    str.characters.count
  2. "Dizenin UTF-16 temsili içindeki 16 bit kod birimleri" istiyorsanız:

    str.utf16.count

Çoğu zaman, 1 ihtiyacınız olan şeydir.

Ne zaman 2 gerekir ? 2 için bir kullanım durumu buldum :

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

1 kullanırsanız , sonuç yanlış olur:

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

7

Böyle deneyebilirsin

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

4
Aynıtest1.utf16count
Sulthan

1
@vladof iyi, "tür" çalışır. Cezar'ın cevabına bakınız.
jbg

6

Swift 2.x'te, bir dizenin uzunluğunu nasıl bulacağınız aşağıda açıklanmıştır

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

24 döndürür


5

Swift 2.0: Sayım yapın: yourString.text.characters.count

Bunun ne kadar yararlı olduğuna dair eğlenceli bir örnek, bir UITextView içindeki bir sayıdan (örneğin 150) bir karakter geri sayımını göstermek olacaktır:

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

4

Swift4'te her zaman string.countbugüne kadar kullandım ki

string.endIndex.encodedOffset

çünkü daha hızlıdır - 50 000 karakter için dize yaklaşık 6 kat daha hızlıdır .count. .countDize uzunluğuna bağlıdır ama .endIndex.encodedOffsetyok.

Ama bir HAYIR var. Emojisi olan dizeler için iyi değildir, yanlış sonuç verir, bu yüzden sadece .countdoğrudur.


3

In Swift 4 : string yaparsa Unicode karakterleri sonra aşağıdaki kullanmak içermez

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

Dize unicode karakterleri içeriyorsa aşağıdakileri kullanın:

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

Neden kullanmak istersiniz utf8.count? Bu karakter sayısını vermez. Dizenin UTF-8 kodlaması için gereken bayt sayısını verir.
rmaddy

2

Xcode 6.1.1'de

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

Beyinciklerin her küçük versiyonda bunu değiştireceğini düşünüyorum.


2

Metin görünümünüzden veya metin alanınızdan dize değeri alın:

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

Dizedeki karakter sayısını bulun:

let numberOfChars = textlength.characters.count

2

İşte yaptığım şey

let replacementTextAsDecimal = Double(string)

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

Ben sadece dize uzunluğu almak daha fazlasını yapmaya çalışıyorum düşünüyorum ve her durumda bu eksik görünüyor (ayrıca bir return truedurumda olmamalı ?). Lütfen tekrar kontrol edip, cevabınızı düzenleyebilir misiniz? Teşekkür ederim!
Fabio,

2

Swift 3 ile karşılaştırıldığında Swift 4 güncellemesi

Swift 4, String'de bir karakter dizisi ihtiyacını ortadan kaldırır. Bu, countönce karakter dizisini almadan önce bir dizeyi doğrudan çağırabileceğiniz anlamına gelir .

"hello".count                  // 5

Oysa hızlı 3'te, karakterler dizisini almanız ve daha sonra bu dizideki öğeyi saymanız gerekir. charactersBelirtilen dizenin karakter dizisine erişmeye devam edebileceğiniz için, aşağıdaki yöntem hala hızlı 4.0'da kullanılabilir.

"hello".characters.count       // 5

Swift 4.0 ayrıca Unicode 9'u benimser ve şimdi grafik kümelerini yorumlayabilir. Örneğin, bir emoji'ye güvenmek, hızlı 3.0'da 1 verir, 1'den büyük sayılar alabilirsiniz.

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

2

Hızlı 4

let str =  "Your name"

str.count 

Unutmayın: Boşluk sayısında da sayılır


2

Uzunluğu basitçe bir uzantı yazarak alabilirsiniz:

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)

Bu, Düzenli Swift Dizesindeki karakterleri sayar

countElements((newString as String))    

Bu, bir NSString'deki karakterleri sayar


1

Swift'te String'i saymanın en iyi yolu şudur:

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

2
Sadece count (str) kullanmalısınız. Tu string count (str.utf16) ile alt string avansını deneyin ()
Leo Dabus

1

Dize ve NSString ücretsiz köprüdür, böylece NSString için kullanılabilir tüm yöntemleri hızlı String ile kullanabilirsiniz

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

1
test1.characters.count

dizenizdeki harflerin / sayıların vb. sayısını alırsınız.

örn:

test1 = "StackOverflow"

print(test1.characters.count)

( " 13 " yazdırır )


1

Apple diğer ana dilden farklı kıldı. Mevcut yol:

test1.characters.count

Ancak, dikkatli olmak için, uzunluk derken, bayt sayısı değil karakter sayımı anlamına gelirsiniz, çünkü ascii olmayan karakterler kullandığınızda bu ikisi farklı olabilir.

Örneğin; "你好啊hi".characters.countsize 5 verecek ama bu bayt sayısı değil. Gerçek bayt sayısını elde etmek için yapmanız gerekir "你好啊hi".lengthOfBytes(using: String.Encoding.utf8). Bu size 11 verecek.


1

Şu anda (Swift 2.3'te) kullanıyorsanız:

myString.characters.count 

yöntem bir "Distance" türü döndürür, eğer bir Integer döndürmek için yönteme ihtiyacınız varsa cast şöyle yazmalısınız:

var count = myString.characters.count as Int

2
DistanceArasında String.CharacterView olan Int bu döküm gerek yoktur olmalı.
Martin R
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.