Как сравнить две строки без учета регистра на языке Swift?

97

Как мы можем сравнить две строки в быстром игнорировании? например:

var a = "Cash"
var b = "cash"

Есть ли какой-нибудь метод, который вернет истину, если мы сравним var a и var b

ак_тяги
источник
1
Вы можете преобразовать оба в нижний регистр, прежде чем проводить сравнение.
Дино Тв
9
Просто обратите внимание, lowercaseStringчто это упомянуто в некоторых ответах не удастся на некоторых языках (например, Straße! = STRASSE)
Alladinian
@Alladinian, как бы вы тогда посоветовали это сделать? Большинство примеров для решения этой проблемы показывают преобразование в верхний или нижний регистр?
Стив
5
@Steve Apple предлагает caseInsensitiveCompare:и localizedCaseInsensitiveCompare:вместо этого
Alladinian
3
@ Стив Конечно! (вы можете попробовать "Straße".localizedCaseInsensitiveCompare("STRASSE")- не забудьте импортировать Foundation)
Alladinian

Ответы:

14

Попробуй это:

var a = "Cash"
var b = "cash"
let result: NSComparisonResult = a.compare(b, options: NSStringCompareOptions.CaseInsensitiveSearch, range: nil, locale: nil)

// You can also ignore last two parameters(thanks 0x7fffffff)
//let result: NSComparisonResult = a.compare(b, options: NSStringCompareOptions.CaseInsensitiveSearch)

Результат - это тип перечисления NSComparisonResult:

enum NSComparisonResult : Int {

    case OrderedAscending
    case OrderedSame
    case OrderedDescending
}

Итак, вы можете использовать оператор if:

if result == .OrderedSame {
    println("equal")
} else {
    println("not equal")
}
Грег
источник
Если я правильно помню, параметры диапазона и языкового стандарта являются необязательными и могут быть полностью опущены.
Мик МакКаллум,
3
Да, действительно, я хотел показать весь метод со всеми параметрами.
Грег
Здесь у вас должен быть правильный ответ. Сравнение строк - это не только знание того, равны они или нет,
Микаэль
184

Попробуй это :

Для более старых свифтов:

var a : String = "Cash"
var b : String = "cash"

if(a.caseInsensitiveCompare(b) == NSComparisonResult.OrderedSame){
    println("voila")
}

Swift 3+

var a : String = "Cash"
var b : String = "cash"

if(a.caseInsensitiveCompare(b) == .orderedSame){
    print("voila")
}
iAnurag
источник
13
В Swift 3 нужно использоватьa.caseInsensitiveCompare(b) == ComparisonResult.orderedSame
ажидков
3
Примечание: caseInsensitiveCompare(_:)не входит в стандартную библиотеку Swift, скорее, это часть Foundationплатформы, поэтому требуется import Foundation.
chrisamanse
Есть ли причина, почему это лучше a.lowercased() == b.lowercased()?
Джоуи
@jowie, как упоминалось в других комментариях, использование lower / uppercased () может не работать на некоторых языках.
cumanzor
36

caseInsensitiveCompareМетод использования :

let a = "Cash"
let b = "cash"
let c = a.caseInsensitiveCompare(b) == .orderedSame
print(c) // "true"

ComparisonResult сообщает вам, какое слово идет раньше другого в лексикографическом порядке (т. Е. Какое слово идет ближе к началу словаря). .orderedSameозначает, что строки окажутся в одном месте в словаре

Сергей Калиниченко
источник
что .orderedSameзначит? В документах просто сказать два операнд равен . Но почему здесь используется слово «порядок»? Есть последовательность или что-то в этом роде? А что значит Левый операнд меньше правого. ( .orderedAscending) означает для строк
Дорогая,
1
Результат @Honey Comparison говорит вам, какое слово идет раньше другого в лексикографическом порядке (то есть какое слово ближе к началу словаря). .orderedSameозначает, что строки окажутся в одном месте в словаре.
Сергей Калиниченко
1
@Honey .orderedSame- это сокращение от ComparisonResult.orderSame... вам не нужно называть тип, поскольку компилятор знает, что caseInsensitiveCompareвозвращает ComparisonResult. «Два операнда равны» - они равны согласно определенному порядку ... очевидно, «Cash» и «cash» не являются идентичными строковыми значениями. «Но почему здесь используется слово« порядок »?» - потому что это результат упорядоченного сравнения. Другие ценности orderedAscendingи orderedDescending... это не просто вопрос того же или другого. Что касается «меньшего»: строки подобны числам в большом основании.
Джим Балтер
1
Мне кажется, это ужасный дизайн API. Подпись нелегко читать ... Сделать ее a.caseInsensitiveCompare(b, comparing: .orderedSame)было бы более читабельно ...
Дорогая,
25
if a.lowercaseString == b.lowercaseString {
    //Strings match
}
Стив
источник
2
Pure Swift - это то, что вам нужно. Нет необходимости в фундаменте.
Александр - Восстановить Монику
2
Преобразование регистра и последующее сравнение неверно. См. Комментарии под вопросом.
Джим Балтер,
1
@JimBalter Я бы не сказал, что это «неправильно», поскольку он отвечает примеру, приведенному в вопросе OP. Для тех из нас, кому не нужна поддержка локализации, это намного проще!
toddg
4
^ Нет, это неправильно. То, что что-то происходит, для одного примера, не имеет значения. Этот хак совсем не «чище». Принятый ответ дает правильное, чистое решение.
Джим Балтер
8

ПРАВИЛЬНЫЙ СПОСОБ:

let a: String = "Cash"
let b: String = "cash"

if a.caseInsensitiveCompare(b) == .orderedSame {
    //Strings match 
}

Обратите внимание: ComparisonResult.orderedSame также может быть сокращено как .orderedSame.

ДРУГИЕ СПОСОБЫ:

а.

if a.lowercased() == b.lowercased() {
    //Strings match 
}

б.

if a.uppercased() == b.uppercased() {
    //Strings match 
}

c.

if a.capitalized() == b.capitalized() {
    //Strings match 
}
Саураб Бхатия
источник
7

Мог бы просто свернуть свой:

func equalIgnoringCase(a:String, b:String) -> Bool {
    return a.lowercaseString == b.lowercaseString
}
матовый
источник
3
Преобразование регистра и последующее сравнение неверно. См. Комментарии под вопросом.
Джим Балтер
7

localizedCaseInsensitiveContains : Возвращает, содержит ли получатель заданную строку, выполняя поиск без учета регистра и с учетом локали

if a.localizedCaseInsensitiveContains(b) {
    //returns true if a contains b (case insensitive)
}

Отредактировано :

caseInsensitiveCompare : возвращает результат вызова compare (_: options :) с NSCaseInsensitiveSearch в качестве единственной опции.

if a.caseInsensitiveCompare(b) == .orderedSame {
    //returns true if a equals b (case insensitive)
}
cgeek
источник
1
Вопрос в сравнении, а не в сдерживании.
Джим Балтер
Если «a содержит b» и «b содержит a» , они равны. Так что это, безусловно, возможное решение, даже если оно может быть не самым эффективным.
Филипп Маурер
1

Вы также можете сделать все буквы прописными (или строчными) и посмотреть, совпадают ли они.

var a = “Cashvar b = “CAShif a.uppercaseString == b.uppercaseString{
  //DO SOMETHING
}

Это сделает обе переменные ”CASH”равными и, следовательно, равными.

Вы также можете сделать Stringрасширение

extension String{
  func equalsIgnoreCase(string:String) -> Bool{
    return self.uppercaseString == string.uppercaseString
  }
}

if "Something ELSE".equalsIgnoreCase("something Else"){
  print("TRUE")
}
milo526
источник
3
Преобразование регистра и последующее сравнение неверно. См. Комментарии под вопросом.
Джим Балтер,
1

Пример сравнения телефонных номеров; используя Swift 4.2

var selectPhone = [String]()

if selectPhone.index(where: {$0.caseInsensitiveCompare(contactsList[indexPath.row].phone!) == .orderedSame}) != nil {
    print("Same value")
} else {
    print("Not the same")
}
икбал
источник
0

Swift 4, я пошел по маршруту расширения String, используя caseInsensitiveCompare () в качестве шаблона (но позволяя операнду быть необязательным). Вот площадка, которую я использовал для сборки (новинка в Swift, поэтому отзывы более чем приветствуются).

import UIKit

extension String {
    func caseInsensitiveEquals<T>(_ otherString: T?) -> Bool where T : StringProtocol {
        guard let otherString = otherString else {
            return false
        }
        return self.caseInsensitiveCompare(otherString) == ComparisonResult.orderedSame
    }
}

"string 1".caseInsensitiveEquals("string 2") // false

"thingy".caseInsensitiveEquals("thingy") // true

let nilString1: String? = nil
"woohoo".caseInsensitiveEquals(nilString1) // false
Уильям Т. Маллард
источник
2
Вы можете просто использовать .orderedSameвместо ComparisonResult.orderedSame.
Джим Балтер
0

Вы можете просто написать расширение String для сравнения всего в нескольких строчках кода.

extension String {

    func compare(_ with : String)->Bool{
        return self.caseInsensitiveCompare(with) == .orderedSame
    } 
}
Муджахид Латиф
источник
0

Для Swift 5 Игнорирование регистра и сравнение двух строк

var a = "cash"
var b = "Cash"
if(a.caseInsensitiveCompare(b) == .orderedSame){
     print("Ok")
}
М Муртеза
источник
-1

Swift 3

if a.lowercased() == b.lowercased() {

}
DoubleK
источник
2
Это не правильно. См. Комментарии под вопросом.
Джим Балтер
-1

Swift 3 : вы можете определить своего собственного оператора, например ~=.

infix operator ~=

func ~=(lhs: String, rhs: String) -> Bool {
   return lhs.caseInsensitiveCompare(rhs) == .orderedSame
}

Что затем можно попробовать на детской площадке

let low = "hej"
let up = "Hej"

func test() {
    if low ~= up {
        print("same")
    } else {
        print("not same")
    }
}

test() // prints 'same'
Саджон
источник
Я не отрицал это, но обратите внимание, что это, как правило, довольно плохая идея, поскольку указанный выше оператор сопоставления пользовательского шаблона будет иметь приоритет над сопоставлением собственного шаблона, обычно используемым при сопоставлении Stringэкземпляров друг с другом (или с другими Stringлитералами). Представьте let str = "isCAMELcase"быть переключен, с футляром следующим образом : case "IsCamelCase": ... . С помощью описанного выше метода это caseбудет успешно введено, чего нельзя ожидать от стандартной реализации Stringсопоставления с образцом в библиотеках. Обновленный ответ Swift 3 все еще хорош, но ...
dfrib
... рассмотрите возможность использования пользовательской функции (или Stringрасширения) в качестве помощника, указанного выше, вместо того, чтобы переопределять Stringсопоставление с образцом по умолчанию .
dfrib
-1
extension String
{
    func equalIgnoreCase(_ compare:String) -> Bool
    {
        return self.uppercased() == compare.uppercased()
    }
}

образец использования

print("lala".equalIgnoreCase("LALA"))
print("l4la".equalIgnoreCase("LALA"))
print("laLa".equalIgnoreCase("LALA"))
print("LALa".equalIgnoreCase("LALA"))
Лухуйя
источник
1
Это не работает для некоторых строк на некоторых языках ... см. Комментарии под вопросом и множество правильных ответов, некоторые из которых - включая принятый - предшествовали вашему на годы.
Джим Балтер
-2

Swift 3:

Вы также можете использовать локализованное сравнение двух строк без учета регистра, и оно возвращает Bool

var a = "cash"
var b = "Cash"

if a.localizedCaseInsensitiveContains(b) {
    print("Identical")           
} else {
    print("Non Identical")
}
Кегам К.
источник
2
Ваше решение неверно. Рассмотрим строки "casha" и "Cash"
clarkcox3