Lấy độ dài của Chuỗi


781

Làm thế nào để bạn có được chiều dài của một String? Ví dụ: tôi có một biến được định nghĩa như:

var test1: String = "Scott"

Tuy nhiên, tôi dường như không thể tìm thấy một phương thức độ dài trên chuỗi.



Tôi đã phải di chuyển rất nhiều mã theo cách thủ công vì Swift 3. Vì vậy, tôi quyết định tạo tiện ích mở rộng. Vì vậy, bây giờ, nếu phải nâng cấp lên một bản phát hành chính mới, tôi chỉ cần di chuyển phần mở rộng. Tại đây bạn có thể tìm thấy một số tiện ích mở rộng Swift 3 mà tôi đã tạo. github.com/tukur187/Swift3
Shkelzen

Câu trả lời:


1284

Kể từ Swift 4+

Nó chỉ:

test1.count

vì lý do.

(Cảm ơn Martin R)

Kể từ Swift 2:

Với Swift 2, Apple đã thay đổi các chức năng toàn cầu thành các tiện ích mở rộng giao thức, tiện ích mở rộng phù hợp với bất kỳ loại nào phù hợp với giao thức. Do đó, cú pháp mới là:

test1.characters.count

(Cảm ơn JohnDifool vì đã ngẩng cao đầu)

Kể từ Swift 1

Sử dụng phương thức đếm ký tự:

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

ngay từ Hướng dẫn Apple Swift

(lưu ý, đối với các phiên bản Swift sớm hơn 1.2, điều này sẽ countElements(unusualMenagerie)thay thế)

cho biến của bạn, nó sẽ là

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

Hoặc bạn có thể sử dụng test1.utf16count


11
Điều thú vị là CountElements là một chức năng toàn cầu. Có một danh sách các chức năng toàn cầu?
Scott Walter

7
Vấn đề với CountElements là nó được khai báo như sau: func CountElements <T> (x: T) -> T.IndexType.DistanceType và kiểu trả về không chấp nhận thao tác +.
MarkAurelius

288
Thật quá khó để thêm một phương thức str.length. (giơ nắm đấm lên trong cơn giận dữ)
botbot

13
Với Swift 2, tôi chỉ có thể làm việc này: hãy để len ​​= test1.char character.count
Laurent

7
Lưu ý rằng với Swift 4, nó sẽ được string.count.
Martin R

335

TLDR:

Đối với Swift 2.0 và 3.0, hãy sử dụng test1.characters.count. Nhưng, có một vài điều bạn nên biết. Vì vậy, đọc tiếp.

Đếm các ký tự trong Swift

Trước Swift 2.0, countlà một chức năng toàn cầu. Kể từ Swift 2.0, nó có thể được gọi là một hàm thành viên.

test1.characters.count

Nó sẽ trả về số lượng ký tự Unicode thực tế trong một String, do đó, đây là cách thay thế chính xác nhất theo nghĩa, nếu bạn in chuỗi và đếm các ký tự bằng tay, bạn sẽ nhận được kết quả tương tự.

Tuy nhiên, do cách thức Stringsđược triển khai trong Swift, các nhân vật không phải lúc nào cũng chiếm cùng một bộ nhớ, vì vậy hãy lưu ý rằng điều này hoạt động hoàn toàn khác so với các phương thức đếm ký tự thông thường trong các ngôn ngữ khác.

Ví dụ, bạn cũng có thể sử dụng test1.utf16.count

Nhưng, như đã nêu dưới đây, giá trị trả về là không đảm bảo được tương tự như gọi counttrên characters.

Từ tài liệu tham khảo ngôn ngữ:

Các cụm grapheme mở rộng có thể bao gồm một hoặc nhiều vô hướng Unicode. Điều này có nghĩa là các nhân vật khác nhau, và các cách thể hiện khác nhau của cùng một nhân vật có thể yêu cầu số lượng bộ nhớ khác nhau để lưu trữ. Do đó, các ký tự trong Swift không chiếm cùng một lượng bộ nhớ trong biểu diễn của một chuỗi. Kết quả là, số lượng ký tự trong một chuỗi không thể được tính mà không lặp qua chuỗi để xác định ranh giới cụm grapheme mở rộng của nó. Nếu bạn đang làm việc với các giá trị chuỗi đặc biệt dài, hãy lưu ý rằng thuộc tính ký tự phải lặp qua các vô hướng Unicode trong toàn bộ chuỗi để xác định các ký tự cho chuỗi đó.

Số lượng ký tự được trả về bởi thuộc tính ký tự không phải lúc nào cũng giống với thuộc tính độ dài của một NSString có chứa các ký tự giống nhau. Độ dài của một NSString dựa trên số đơn vị mã 16 bit trong biểu diễn UTF-16 của chuỗi chứ không phải số cụm grapheme mở rộng Unicode trong chuỗi.

Một ví dụ minh họa hoàn hảo tình huống được mô tả ở trên là kiểm tra độ dài của chuỗi chứa một ký tự biểu tượng cảm xúc, như được chỉ ra bởi n00neimp0rtant trong các bình luận.

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

26
Tôi đánh giá cao câu trả lời chi tiết và thận trọng của bạn, nhưng tôi phải thừa nhận nó khiến tôi không yên tâm. Bạn đã cho tôi 3 cách để có được độ dài của một chuỗi, tất cả đều từ chối trách nhiệm rằng các câu trả lời họ đưa ra có thể không phải là điều bạn mong đợi. Có thực sự không có cách đáng tin cậy nào được tích hợp trong Swift để có được giá trị độ dài chính xác, đáng tin cậy của chuỗi không?
n00neimp0rtant

6
@ n00neimp0rtant. Xin lỗi nếu tôi không làm rõ. Giải pháp đầu tiên ( countElements()) có được số lượng ký tự chính xác trong Chuỗi. Nó có thể khác với những gì bạn nhận được khi gọi [str length]trong Objective-C, bởi vì lengthphương thức giả định tất cả các ký tự trong chuỗi bao gồm các đơn vị mã 16 bit, trong khi countElements()có được số lượng ký tự Unicode thực tế. Tuy nhiên, hầu hết thời gian tất cả các lựa chọn thay thế ở trên sẽ trả về cùng một kết quả, đặc biệt nếu bạn đang làm việc với các ký tự phổ biến bằng tiếng Anh.
Cezar

2
@ n00neimp0rtant Tôi đã điều chỉnh câu trả lời của mình một chút để thử và làm cho nó rõ ràng hơn.
Cezar

2
Tôi thấy những gì bạn có nghĩa là bây giờ. Tôi vừa thử độ dài của một chuỗi chứa một ký tự Emoji; Objective-C cho tôi giá trị là 4 và Swift cho tôi giá trị là 1. Vì vậy, nó thực sự có vẻ chính xác hơn (và do đó, trớ trêu thay "không như tôi mong đợi" = P). Cảm ơn bạn đã làm rõ!
n00neimp0rtant

1
@ n00neimp0rtant Chính xác! Đó là một ví dụ hoàn hảo. Tôi thậm chí sẽ thêm nó vào câu trả lời
Cezar

92

Cập nhật Swift 1.2: Không còn là số đếm để đếm kích thước của bộ sưu tập. Chỉ cần sử dụng chức năng đếm thay thế: đếm ("Swift")

Swift 2.0, 3.0 và 3.1:

hãy để strLạng = string.char character.count

Swift 4.2 (4.0 trở đi): [Tài liệu Apple - Chuỗi]

hãy để strLạng = string.count


61

Swift 1.1

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

Swift 1.2

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

Swift 2.0

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

Swift 4.2

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

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

6
Có, chúng tôi cần một lớp trừu tượng cho cú pháp của Swift đang thay đổi hàng tháng!
Cosmin

@Lee Điều này không hoạt động trong swift 4. vì các ký tự không được dùng nữa. Các nốt ruồi chạy quanh vẫn tiếp tục. thở dài
eonist

48

Swift 4

"string".count

;)

Swift 3

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

sử dụng

"string".length


Nó trả về String.CharacterView.IndexDistance. Còn Int thì sao?
eonist

@GitSync ở đâu? Tôi không hiểu bạn
Vyacheslav

@Vyacheslav trong swift 4 "chuỗi" .count trả về String.CharacterView.IndexDistance Xem câu trả lời của tôi tại đây: stackoverflow.com/a/47203597/5389500 để nhận int trong swift 3 và 4
eonist

Tôi đã thử nghiệm đây là sân chơi:
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

Nếu bạn chỉ đang cố gắng xem liệu một chuỗi có trống hay không (kiểm tra độ dài bằng 0), Swift cung cấp một phương thức kiểm tra boolean đơn giản trên String

myString.isEmpty

Mặt khác của đồng tiền này là mọi người hỏi trong ObjectiveC làm thế nào để hỏi xem một chuỗi có trống không trong đó câu trả lời là kiểm tra độ dài 0:

NSString trống


18

tl; dr Nếu bạn muốn độ dài của một loại Chuỗi theo số lượng ký tự có thể đọc được của con người, hãy sử dụng CountElements () . Nếu bạn muốn biết độ dài về số lượng cụm grapheme mở rộng , hãy sử dụng end Index . Đọc để biết chi tiết.

Kiểu Chuỗi được triển khai dưới dạng tập hợp có thứ tự (nghĩa là chuỗi) các ký tự Unicode và nó tuân theo giao thức CollectionType , phù hợp với giao thức _CollectionType , là loại đầu vào được mong đợi bởi CountElements () . Do đó, CountElements () có thể được gọi, chuyển một kiểu Chuỗi và nó sẽ trả về số lượng ký tự.

Tuy nhiên, trong phù hợp với CollectionType , mà trong chiếu theo lần lượt _CollectionType , Chuỗi cũng thực hiện các startIndexendIndex tính tính, mà thực sự đại diện cho vị trí của chỉ số trước các cụm ký tự đầu tiên, và vị trí của các chỉ số sau cụm ký tự cuối cùng, tương ứng . Vì vậy, trong chuỗi "ABC", vị trí của chỉ số trước A là 0 và sau C là 3. Do đó, end Index = 3, cũng là độ dài của chuỗi.

Vì vậy, end Index có thể được sử dụng để lấy độ dài của bất kỳ loại Chuỗi nào, phải không?

Chà, không phải lúc nào ... Các ký tự Unicode thực sự là các cụm grapheme mở rộng , là các chuỗi của một hoặc nhiều vô hướng Unicode được kết hợp để tạo ra một ký tự có thể đọc được bằng con người.

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

CircledStar là một ký tự đơn được tạo thành từ U + 2606 (một ngôi sao trắng) và U + 20DD (một vòng tròn bao quanh kết hợp). Hãy tạo một chuỗi từ circledStar và so sánh kết quả của countElements ()endIndex .

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

15

Trong Swift 2.0 countkhông hoạt động nữa. Bạn có thể sử dụng điều này thay thế:

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

14

Đây là một cái gì đó ngắn hơn và tự nhiên hơn so với sử dụng chức năng toàn cầu:

aString.utf16count

Tôi không biết nếu nó có sẵn trong phiên bản beta 1. Nhưng nó chắc chắn có trong phiên bản beta 2.


2
Xem câu trả lời của Cezar. Điều này sẽ không nhất thiết phải cung cấp cho bạn số lượng ký tự của người khác trong chuỗi, đối với hầu hết định nghĩa của mọi người về nhân vật này. Sau đó, một lần nữa, Objective-C cũng không quyết định bạn có quan tâm hay không.
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

Đã cập nhật cho Xcode 6 beta 4, thay đổi phương thức utf16count -> utf16Count

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

Hoặc là

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

Khi bạn đang sử dụng các chuỗi phức tạp với biểu tượng cảm xúc, câu trả lời utf16countsẽ sai
Victor Sigler

10

Kể từ Swift 1.2 utf16Countđã bị xóa. Bây giờ bạn nên sử dụng count()hàm toàn cục và chuyển giao dạng UTF16 của chuỗi. Ví dụ dưới đây ...

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

1
Có chậm hơn .utf16count không?
samir105

1
Có vẻ như tốc độ tương tự như .utf16count, nhanh hơn nhiều so với đếm (chuỗi)
samir105

8

Đối với Xcode 7.3 và Swift 2.2.

let str = "🐶"
  1. Nếu bạn muốn số lượng nhân vật trực quan:

    str.characters.count
  2. Nếu bạn muốn "đơn vị mã 16 bit trong biểu diễn UTF-16 của chuỗi":

    str.utf16.count

Hầu hết thời gian, 1 là những gì bạn cần.

Khi nào bạn cần 2 ? Tôi đã tìm thấy một trường hợp sử dụng cho 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

Nếu bạn sử dụng 1 , kết quả không chính xác:

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

7

Bạn có thể thử như thế này

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

4
Điều đó cũng giống nhưtest1.utf16count
Sulthan

1
@vladof tốt, nó là loại công việc của thành phố. Xem câu trả lời của Cezar.
jbg

6

trong Swift 2.x sau đây là cách tìm độ dài của chuỗi

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

trả lại 24


5

Swift 2.0: Nhận số đếm: yourString.text.characters.count

Ví dụ thú vị về cách hữu ích này sẽ hiển thị đếm ngược ký tự từ một số (ví dụ 150) trong UITextView:

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

4

Trong swift4 tôi đã luôn sử dụng string.countcho đến ngày hôm nay tôi đã thấy rằng

string.endIndex.encodedOffset

là sự thay thế tốt hơn bởi vì nó nhanh hơn - cho chuỗi 50 000 ký tự nhanh hơn khoảng 6 lần .count. Việc .countphụ thuộc vào độ dài chuỗi nhưng .endIndex.encodedOffsetkhông.

Nhưng có một KHÔNG. Nó không tốt cho chuỗi với biểu tượng cảm xúc, nó sẽ cho kết quả sai, vì vậy chỉ .countcó chính xác.


3

Trong Swift 4 : Nếu chuỗi không chứa các ký tự unicode thì hãy sử dụng như sau

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

Nếu chuỗi chứa ký tự unicode thì sử dụng như sau:

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

Tại sao bạn muốn sử dụng utf8.count? Điều đó không đưa ra số lượng nhân vật. Nó đưa ra số byte cần thiết cho mã hóa UTF-8 của chuỗi.
rmaddy

2

Trong Xcode 6.1.1

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

Tôi nghĩ rằng những bộ não sẽ thay đổi điều này trên mỗi phiên bản nhỏ.


2

Nhận giá trị chuỗi từ textview hoặc textfield của bạn:

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

Tìm số lượng các ký tự trong chuỗi:

let numberOfChars = textlength.characters.count

2

Đây là những gì tôi đã làm

let replacementTextAsDecimal = Double(string)

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

Tôi nghĩ rằng bạn đang cố gắng làm nhiều hơn là chỉ lấy độ dài của chuỗi, và trong mọi trường hợp, điều này có vẻ không hoàn chỉnh (cũng không nên có return truetrường hợp nào?). Bạn có thể vui lòng kiểm tra lại và, trong trường hợp, chỉnh sửa câu trả lời của bạn? Cảm ơn bạn!
Fabio nói Phục hồi lại

2

Cập nhật Swift 4 so với swift 3

Swift 4 loại bỏ sự cần thiết của một mảng ký tự trên Chuỗi. Điều này có nghĩa là bạn có thể gọi trực tiếp counttrên một chuỗi mà không cần lấy mảng ký tự trước.

"hello".count                  // 5

Trong khi ở swift 3, bạn sẽ phải lấy mảng ký tự và sau đó đếm phần tử trong mảng đó. Lưu ý rằng phương thức sau đây vẫn có sẵn trong swift 4.0 vì bạn vẫn có thể gọi charactersđể truy cập mảng ký tự của chuỗi đã cho

"hello".characters.count       // 5

Swift 4.0 cũng áp dụng Unicode 9 và giờ đây nó có thể diễn giải các cụm grapheme. Ví dụ: tính vào biểu tượng cảm xúc sẽ cung cấp cho bạn 1 trong khi ở swift 3.0, bạn có thể nhận được số lượng lớn hơn 1.

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

2

Swift 4

let str =  "Your name"

str.count 

Ghi nhớ: Không gian cũng được tính vào số


2

Bạn có thể nhận được độ dài chỉ bằng cách viết một phần mở rộng:

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)

Điều này đếm các ký tự trong Chuỗi Swift thông thường

countElements((newString as String))    

Điều này đếm các ký tự trong một NSString


1

Cách tốt nhất để đếm Chuỗi trong Swift là:

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

2
Bạn chỉ nên sử dụng tính (str). Hãy thử sử dụng số đếm (str.utf16) với chuỗi phụ trước ()
Leo Dabus

1

Chuỗi và NSString là cầu nối miễn phí, do đó bạn có thể sử dụng tất cả các phương thức có sẵn cho NSString với Chuỗi nhanh

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

1
test1.characters.count

sẽ giúp bạn có được số lượng chữ cái / số vv trong chuỗi của bạn.

Ví dụ:

test1 = "StackOverflow"

print(test1.characters.count)

( in " 13 ")


1

Apple làm cho nó khác với ngôn ngữ chính khác. Cách hiện tại là gọi:

test1.char character.count

Tuy nhiên, để cẩn thận, khi bạn nói độ dài, bạn có nghĩa là số lượng ký tự không phải là số byte, bởi vì hai ký tự đó có thể khác nhau khi bạn sử dụng các ký tự không phải mã ascii.

Ví dụ; "你好啊hi".characters.countsẽ cung cấp cho bạn 5 nhưng đây không phải là số byte. Để có được số byte thực sự, bạn cần phải làm "你好啊hi".lengthOfBytes(using: String.Encoding.utf8). Điều này sẽ cung cấp cho bạn 11.


1

Ngay bây giờ (trong Swift 2.3) nếu bạn sử dụng:

myString.characters.count 

phương thức sẽ trả về loại "Khoảng cách", nếu bạn cần phương thức trả về một Số nguyên, bạn nên nhập kiểu như vậy:

var count = myString.characters.count as Int

2
Các Distancesố String.CharacterView Int , không nên có nhu cầu về dàn diễn viên này.
Martin R
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.