Мне пришлось перенести много кода вручную из-за Swift 3. Поэтому я решил создать расширения. Так что теперь, если придется переходить на новый основной выпуск, мне нужно перенести только расширение. Здесь вы можете найти некоторые расширения Swift 3, которые я создал. github.com/tukur187/Swift3
Шкельзен
Ответы:
1284
Начиная с Swift 4+
Это просто:
test1.count
по причинам.
(Спасибо Мартину Р.)
Начиная с Swift 2:
С Swift 2 Apple изменила глобальные функции на расширения протокола, расширения, которые соответствуют любому типу, соответствующему протоколу. Таким образом, новый синтаксис:
test1.characters.count
(Спасибо JohnDifool за советы)
По состоянию на Свифт 1
Используйте метод подсчета символов:
let unusualMenagerie ="Koala 🐨, Snail 🐌, Penguin 🐧, Dromedary 🐪"
println("unusualMenagerie has \(count(unusualMenagerie)) characters")// prints "unusualMenagerie has 40 characters"
прямо из руководства Apple Swift
(обратите внимание, для версий Swift более ранних, чем 1.2, это будет countElements(unusualMenagerie)вместо)
для вашей переменной это было бы
length = count(test1)// was countElements in earlier versions of Swift
Интересно, что countElements является глобальной функцией. Есть ли список глобальных функций?
Скотт Уолтер
7
Проблема с countElements состоит в том, что он объявлен так: func countElements <T> (x: T) -> T.IndexType.DistanceType, а возвращаемый тип не принимает операцию +.
Марк Аврелий
288
Было просто слишком сложно добавить метод str.length. (поднимает кулак в гневе)
ботбот
13
С Swift 2 я могу только заставить это работать: let len = test1.characters.count
Laurent
7
Обратите внимание, что с Swift 4 это будет string.count.
Мартин Р
335
TLDR:
Для Swift 2.0 и 3.0 используйте test1.characters.count. Но есть несколько вещей, которые вы должны знать. Итак, читайте дальше.
Подсчет символов в Swift
До Swift 2.0 countбыла глобальная функция. Начиная с Swift 2.0, его можно вызывать как функцию-член.
test1.characters.count
Он вернет фактическое количество символов Unicode в a String, так что это наиболее правильная альтернатива в том смысле, что если вы напечатаете строку и посчитаете символы вручную, вы получите тот же результат.
Однако из-за способа Stringsреализации в Swift символы не всегда занимают одинаковый объем памяти, поэтому имейте в виду, что это ведет себя совершенно иначе, чем обычные методы подсчета символов в других языках.
Например, вы также можете использовать test1.utf16.count
Но, как указано ниже, возвращаемое значение не гарантируется быть такой же , как и вызова countна characters.
Из языковой справки:
Расширенные кластеры графем могут состоять из одного или нескольких скаляров Unicode. Это означает, что различным символам - и различным представлениям одного и того же символа - может потребоваться различное количество памяти для хранения. Из-за этого символы в Swift не занимают одинаковое количество памяти в представлении строки. В результате количество символов в строке не может быть вычислено без итерации по строке для определения границ кластера расширенных графем. Если вы работаете с особенно длинными строковыми значениями, имейте в виду, что свойство символов должно перебирать скаляры Юникода во всей строке, чтобы определить символы для этой строки.
Количество символов, возвращаемых свойством символов, не всегда совпадает со свойством длины строки NSString, содержащей те же символы. Длина строки NSString основана на количестве 16-битных единиц кода в представлении строки UTF-16, а не на количестве кластеров расширенных графем Unicode в строке.
Примером, который отлично иллюстрирует ситуацию, описанную выше, является проверка длины строки, содержащей один символ emoji , как указано в комментариях n00neimp0rtant .
var emoji ="👍"
emoji.characters.count //returns 1
emoji.utf16.count //returns 2
Я ценю ваш подробный и предостерегающий ответ, но должен признать, что это оставило меня в неловком положении. Вы дали мне 3 способа получить длину строки, все с оговоркой, что ответы, которые они дают, могут не соответствовать вашим ожиданиям. Неужели в Swift нет надежного способа получить точное и надежное значение длины строки?
n00neimp0rtant
6
@ n00neimp0rtant. Извините, если я не дал понять. Первое решение ( countElements()) получает точное количество символов в строке. Это может отличаться от того, что вы получите от вызова [str length]в Objective-C, потому что lengthметод предполагает, что все символы в строке состоят из 16-битных кодовых единиц, в то время как countElements()получает фактическое количество символов Unicode. Однако в большинстве случаев все вышеперечисленные альтернативы будут давать одинаковые результаты, особенно если вы работаете с общими символами английского языка.
Цезарь
2
@ n00neimp0rtant Я немного подправил свой ответ, чтобы сделать его более понятным.
Цезарь
2
Теперь я понимаю, что вы имеете в виду. Я просто попытался получить длину строки, содержащей один символ Emoji; Objective-C дал мне значение 4, а Swift дал мне значение 1. Так что на самом деле это кажется более точным (и поэтому, по иронии судьбы, «не то, что я ожидал» = P). Благодарю за разъяснение!
n00neimp0rtant
1
@ n00neimp0rtant Точно! Это прекрасный пример. Я даже добавлю это к ответу
Цезарь
92
Обновление Swift 1.2: больше нет countElements для подсчета размера коллекций. Просто используйте функцию подсчета в качестве замены: count ("Swift")
Возвращает String.CharacterView.IndexDistance. А как насчет Int?
eonist
@ GitSync где? Я не понимаю тебя
Вячеслав
@Vyacheslav in swift 4 "string" .count возвращает String.CharacterView.IndexDistance Смотрите мой ответ здесь: stackoverflow.com/a/47203597/5389500, чтобы получить int в swift 3 и 4
eonist
Я проверял это на детской площадке:
Вячеслав
//: 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))
Вячеслав
25
Если вы просто пытаетесь увидеть, является ли строка пустой или нет (проверка на длину 0), Swift предлагает простой метод логического теста на String
myString.isEmpty
Другой стороной этой монеты были люди, спрашивающие в ObjectiveC, как спросить, была ли строка пустой, где ответ должен был проверить длину 0:
tl; dr Если вы хотите, чтобы длина типа String определялась числом читаемых человеком символов, используйте countElements () . Если вы хотите узнать длину в терминах числа расширенных кластеров графем , используйте endIndex . Продолжайте читать для деталей.
Тип String реализован как упорядоченная коллекция (то есть последовательность) символов Unicode и соответствует протоколу CollectionType , который соответствует протоколу _CollectionType , который является типом ввода, ожидаемым countElements () . Следовательно, можно вызывать countElements () , передавая тип String , и он будет возвращать количество символов.
Однако в соответствии с CollectionType , который в свою очередь соответствует _CollectionType , String также реализует вычисленные свойства startIndex и endIndex , которые фактически представляют позицию индекса перед первым кластером символов и позицию индекса после кластера последнего символа, соответственно , Таким образом, в строке «ABC» позиция индекса до A равна 0, а после C равна 3. Следовательно, endIndex = 3, что также является длиной строки.
Таким образом, endIndex может быть использован для получения длины любого типа String, верно?
Ну, не всегда ... Символы Unicode на самом деле представляют собой расширенные кластеры графем , которые представляют собой последовательности одного или нескольких скаляров Unicode, объединенных для создания единственного читаемого человеком символа.
let circledStar:Character="\u{2606}\u{20DD}"// ☆⃝
circledStar - это одиночный символ, состоящий из U + 2606 (белая звезда) и U + 20DD (объединяющий окружающий круг). Давайте создадим String из circledStar и сравним результаты countElements () и endIndex .
let circledStarString ="\(circledStar)"
countElements(circledStarString)// 1
circledStarString.endIndex //2
Смотрите ответ Цезаря. Это не обязательно даст вам количество «символов» в строке, для большинства людей определение «символ». С другой стороны, и Objective-C - и вам решать, волнует ли вас это или нет.
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"
Когда вы используете сложные строки с эмодзи, ответ utf16countбудет неправильным
Виктор Сиглер,
10
По состоянию на Swift 1.2 utf16Countбыл удален. Теперь вы должны использовать глобальную count()функцию и передать UTF16-представление строки. Пример ниже ...
Кажется, та же скорость, что и .utf16count, намного быстрее, чем count (строка)
samir105
8
Для Xcode 7.3 и Swift 2.2.
let str ="🐶"
Если вы хотите количество визуальных символов:
str.characters.count
Если вам нужны «16-битные единицы кода в строковом представлении UTF-16»:
str.utf16.count
В большинстве случаев 1 - это то, что вам нужно.
Когда вам нужно 2 ? Я нашел вариант использования для 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
Если вы используете 1 , результат неверен:
let result = regex.stringByReplacingMatchesInString(str,
options:NSMatchingOptions.WithTransparentBounds,
range:NSMakeRange(0, str.characters.count), withTemplate:"dog")
print(result)// dogdogdog🐶🐶🐶
В swift4 я всегда использовал string.countдо сегодняшнего дня, я обнаружил, что
string.endIndex.encodedOffset
это лучшая замена, потому что она быстрее - для 50 000 символов строка примерно в 6 раз быстрее, чем .count. .countЗависит от длины строки , но .endIndex.encodedOffsetне делает.
Но есть один НЕТ. Это не хорошо для струн с смайликами, это даст неправильный результат, поэтому только .countправильно.
Я думаю, что вы пытаетесь сделать больше, чем просто получить длину строки, и в любом случае это выглядит неполным (разве не должно быть return trueслучая?). Можете ли вы проверить еще раз и, в случае, отредактировать свой ответ? Спасибо!
Фабио говорит восстановить Монику
2
Обновление Swift 4 по сравнению со Swift 3
Swift 4 устраняет необходимость в массиве символов в строке. Это означает, что вы можете напрямую вызывать countстроку без предварительного получения массива символов.
"hello".count //5
В то время как в Swift 3 вам нужно будет получить массив символов, а затем посчитать элемент в этом массиве. Обратите внимание, что этот следующий метод все еще доступен в swift 4.0, так как вы все равно можете вызвать charactersмассив символов данной строки
"hello".characters.count //5
Swift 4.0 также принимает Unicode 9 и теперь может интерпретировать кластеры графем. Например, если рассчитывать на смайликов, вы получите 1, а в Swift 3.0 вы можете получить больше 1.
"👍🏽".count // Swift 4.0 prints 1, Swift 3.0 prints 2
"👨❤️💋👨".count //Swift4.0 prints 1,Swift3.0 prints 4
Вы можете получить длину, просто написав расширение:
extensionString{// 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
}}
Apple сделала его отличным от других основных языков. Текущий способ заключается в том, чтобы позвонить:
test1.characters.count
Однако, чтобы быть осторожным, когда вы говорите длину, вы имеете в виду количество символов, а не количество байтов, потому что эти два значения могут отличаться, когда вы используете символы не-ascii.
Например;
"你好啊hi".characters.countдаст вам 5, но это не количество байтов. Чтобы получить реальное количество байтов, вам нужно сделать "你好啊hi".lengthOfBytes(using: String.Encoding.utf8). Это даст вам 11.
Ответы:
Начиная с Swift 4+
Это просто:
по причинам.
(Спасибо Мартину Р.)
Начиная с Swift 2:
С Swift 2 Apple изменила глобальные функции на расширения протокола, расширения, которые соответствуют любому типу, соответствующему протоколу. Таким образом, новый синтаксис:
(Спасибо JohnDifool за советы)
По состоянию на Свифт 1
Используйте метод подсчета символов:
прямо из руководства Apple Swift
(обратите внимание, для версий Swift более ранних, чем 1.2, это будет
countElements(unusualMenagerie)
вместо)для вашей переменной это было бы
Или вы можете использовать test1.utf16count
источник
string.count
.TLDR:
Для Swift 2.0 и 3.0 используйте
test1.characters.count
. Но есть несколько вещей, которые вы должны знать. Итак, читайте дальше.Подсчет символов в Swift
До Swift 2.0
count
была глобальная функция. Начиная с Swift 2.0, его можно вызывать как функцию-член.Он вернет фактическое количество символов Unicode в a
String
, так что это наиболее правильная альтернатива в том смысле, что если вы напечатаете строку и посчитаете символы вручную, вы получите тот же результат.Однако из-за способа
Strings
реализации в Swift символы не всегда занимают одинаковый объем памяти, поэтому имейте в виду, что это ведет себя совершенно иначе, чем обычные методы подсчета символов в других языках.Например, вы также можете использовать
test1.utf16.count
Но, как указано ниже, возвращаемое значение не гарантируется быть такой же , как и вызова
count
наcharacters
.Из языковой справки:
Примером, который отлично иллюстрирует ситуацию, описанную выше, является проверка длины строки, содержащей один символ emoji , как указано в комментариях n00neimp0rtant .
источник
countElements()
) получает точное количество символов в строке. Это может отличаться от того, что вы получите от вызова[str length]
в Objective-C, потому чтоlength
метод предполагает, что все символы в строке состоят из 16-битных кодовых единиц, в то время какcountElements()
получает фактическое количество символов Unicode. Однако в большинстве случаев все вышеперечисленные альтернативы будут давать одинаковые результаты, особенно если вы работаете с общими символами английского языка.Обновление Swift 1.2: больше нет countElements для подсчета размера коллекций. Просто используйте функцию подсчета в качестве замены: count ("Swift")Swift 2.0, 3.0 и 3.1:Swift 4.2 (начиная с 4.0): [Документация Apple - Строки]
источник
Swift 1.1
Swift 1.2
Swift 2.0
Swift 4.2
источник
Swift 4
"string".count
;)
Свифт 3
Применение
"string".length
источник
//: 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))
Если вы просто пытаетесь увидеть, является ли строка пустой или нет (проверка на длину 0), Swift предлагает простой метод логического теста на
String
Другой стороной этой монеты были люди, спрашивающие в ObjectiveC, как спросить, была ли строка пустой, где ответ должен был проверить длину 0:
NSString пусто
источник
tl; dr Если вы хотите, чтобы длина типа String определялась числом читаемых человеком символов, используйте countElements () . Если вы хотите узнать длину в терминах числа расширенных кластеров графем , используйте endIndex . Продолжайте читать для деталей.
Тип String реализован как упорядоченная коллекция (то есть последовательность) символов Unicode и соответствует протоколу CollectionType , который соответствует протоколу _CollectionType , который является типом ввода, ожидаемым countElements () . Следовательно, можно вызывать countElements () , передавая тип String , и он будет возвращать количество символов.
Однако в соответствии с CollectionType , который в свою очередь соответствует _CollectionType , String также реализует вычисленные свойства startIndex и endIndex , которые фактически представляют позицию индекса перед первым кластером символов и позицию индекса после кластера последнего символа, соответственно , Таким образом, в строке «ABC» позиция индекса до A равна 0, а после C равна 3. Следовательно, endIndex = 3, что также является длиной строки.
Таким образом, endIndex может быть использован для получения длины любого типа String, верно?
Ну, не всегда ... Символы Unicode на самом деле представляют собой расширенные кластеры графем , которые представляют собой последовательности одного или нескольких скаляров Unicode, объединенных для создания единственного читаемого человеком символа.
circledStar - это одиночный символ, состоящий из U + 2606 (белая звезда) и U + 20DD (объединяющий окружающий круг). Давайте создадим String из circledStar и сравним результаты countElements () и endIndex .
источник
В Swift 2.0
count
больше не работает. Вы можете использовать это вместо:источник
Вот что-то более короткое и более естественное, чем использование глобальной функции:
Я не знаю, доступен ли он в бета-версии 1, хотя. Но это определенно есть в бета-версии 2.
источник
Swift 5.1, 5
источник
Обновлено для Xcode 6 beta 4, измените метод utf16count -> utf16Count
Или
источник
utf16count
будет неправильнымПо состоянию на Swift 1.2
utf16Count
был удален. Теперь вы должны использовать глобальнуюcount()
функцию и передать UTF16-представление строки. Пример ниже ...источник
Для Xcode 7.3 и Swift 2.2.
Если вы хотите количество визуальных символов:
Если вам нужны «16-битные единицы кода в строковом представлении UTF-16»:
В большинстве случаев 1 - это то, что вам нужно.
Когда вам нужно 2 ? Я нашел вариант использования для 2 :
Если вы используете 1 , результат неверен:
источник
Вы можете попробовать вот так
источник
test1.utf16count
в Swift 2.x следующее - как найти длину строки
возвращает 24
источник
Swift 2.0: получить счет:
yourString.text.characters.count
Интересный пример того, как это полезно - показать обратный отсчет символов от некоторого числа (например, 150) в UITextView:
источник
В swift4 я всегда использовал
string.count
до сегодняшнего дня, я обнаружил, чтоэто лучшая замена, потому что она быстрее - для 50 000 символов строка примерно в 6 раз быстрее, чем
.count
..count
Зависит от длины строки , но.endIndex.encodedOffset
не делает.Но есть один НЕТ. Это не хорошо для струн с смайликами, это даст неправильный результат, поэтому только
.count
правильно.источник
В Swift 4 : если строка не содержит символов Юникода, используйте следующее
Если строка содержит символы Юникода, используйте следующее:
источник
utf8.count
? Это не дает количество символов. Он дает количество байтов, необходимое для кодирования строки UTF-8.В Xcode 6.1.1
Я думаю, что Brainiacs изменит это на каждой минорной версии.
источник
Получите строковое значение из вашего текстового представления или текстового поля:
Найдите количество символов в строке:
источник
Вот что я в итоге делал
источник
return true
случая?). Можете ли вы проверить еще раз и, в случае, отредактировать свой ответ? Спасибо!Обновление Swift 4 по сравнению со Swift 3
Swift 4 устраняет необходимость в массиве символов в строке. Это означает, что вы можете напрямую вызывать
count
строку без предварительного получения массива символов.В то время как в Swift 3 вам нужно будет получить массив символов, а затем посчитать элемент в этом массиве. Обратите внимание, что этот следующий метод все еще доступен в swift 4.0, так как вы все равно можете вызвать
characters
массив символов данной строкиSwift 4.0 также принимает Unicode 9 и теперь может интерпретировать кластеры графем. Например, если рассчитывать на смайликов, вы получите 1, а в Swift 3.0 вы можете получить больше 1.
источник
Swift 4
Помните: пробел также учитывается в числе
источник
Вы можете получить длину, просто написав расширение:
источник
Это считает символы в регулярной быстрой строке
Это подсчитывает символы в строке NSString
источник
Лучший способ посчитать String в Swift это:
источник
String и NSString являются бесплатным мостом, поэтому вы можете использовать все методы, доступные для NSString, с помощью swift String.
источник
Вы получите количество букв / цифр и т. д. в вашей строке.
например:
( печатает " 13 ")
источник
Apple сделала его отличным от других основных языков. Текущий способ заключается в том, чтобы позвонить:
test1.characters.count
Однако, чтобы быть осторожным, когда вы говорите длину, вы имеете в виду количество символов, а не количество байтов, потому что эти два значения могут отличаться, когда вы используете символы не-ascii.
Например;
"你好啊hi".characters.count
даст вам 5, но это не количество байтов. Чтобы получить реальное количество байтов, вам нужно сделать"你好啊hi".lengthOfBytes(using: String.Encoding.utf8)
. Это даст вам 11.источник
Прямо сейчас (в Swift 2.3), если вы используете:
метод вернет тип «Distance», если вам нужен метод для возврата Integer, вы должны набрать приведение следующим образом:
источник
Distance
ИзString.CharacterView
этоInt
, не должно быть никакой необходимости в этом броске.