Як порівняти два рядки, ігноруючи регістр мовою Swift?


95

Як можна порівняти два рядки у швидкому ігноруванні регістру? наприклад:

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

Чи існує якийсь метод, який поверне істину, якщо порівняти var a & var b


1
Ви можете перетворити обидва на нижчий регістр, перш ніж робити порівняння.
Dino Tw

8
Тільки зауважимо, lowercaseStringщо це згадується в деяких відповідях, не вдасться на деяких мовах (Straße! = STRASSE наприклад)
Алладініан,

@Alladinian, як би ти запропонував зробити це тоді. Більшість прикладів для вирішення цієї проблеми показують перетворення або на всі великі регістри, або на всі нижчі регістри?
Стів

5
@Steve Apple пропонує caseInsensitiveCompare:& localizedCaseInsensitiveCompare:замість цього
Алладіан

3
@ Steve Звичайно! (можна спробувати "Straße".localizedCaseInsensitiveCompare("STRASSE")- Не забудьте імпортувати Foundation)
Алладиніан

Відповіді:


13

Спробуйте це:

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")
}

Якщо я правильно пам’ятаю, параметри діапазону та мови не є обов’язковими і можуть бути повністю опущені.
Mick MacCallum

3
Так, справді, я хотів показати цілий метод із усіма параметрами.
Грег

Тут ви повинні мати правильну відповідь. Порівняння рядків полягає не лише в тому, щоб знати, рівні вони чи ні,
Мікаель

181

Спробуйте це :

Для старших швидких:

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

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

Свіфт 3+

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

if(a.caseInsensitiveCompare(b) == .orderedSame){
    print("voila")
}

13
У Swift 3 вам потрібно скористатисяa.caseInsensitiveCompare(b) == ComparisonResult.orderedSame
azhidkov

2
Примітка: caseInsensitiveCompare(_:)не входить до стандартної бібліотеки Swift, навпаки, це частина Foundationфреймворку, отже, вимагає import Foundation.
chrisamanse

Чи є якась причина, чому це краще, ніж a.lowercased() == b.lowercased()?
Джові

36

caseInsensitiveCompareМетод використання :

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

Результат порівняння повідомляє, яке слово приходить раніше за інше у лексикографічному порядку (тобто яке з них наближається до передньої частини словника). .orderedSameозначає, що рядки опиняться в тому самому місці словника


що .orderedSameозначає У документах просто сказано, що два операнди рівні . Але чому тут використовується слово «порядок»? Є послідовність чи щось інше? І що означає лівий операнд менше, ніж правий операнд. ( .orderedAscending) означає для струнних
Мед

1
Результат порівняння @Honey вказує, яке слово приходить раніше за інше в лексикографічному порядку (тобто яке з них наближається до передньої частини словника). .orderedSameозначає, що рядки опиняться в тому самому місці словника.
dasblinkenlight

1
@Honey .orderedSame- це скорочення від ComparisonResult.orderSame... не потрібно називати тип, оскільки компілятор знає, що caseInsensitiveCompareповертає a ComparisonResult. "Два операнди рівні" - вони рівні відповідно до конкретного порядку ... очевидно, "Готівка" та "Готівка" не є однаковими рядковими значеннями. "Але чому тут використовується слово" порядок "?" - тому що це результат впорядкованого порівняння. Інші цінності - це ... orderedAscendingі orderedDescendingсправа не лише в тому ж чи іншому. Що стосується "менших": рядки схожі на числа у великій основі.
Jim Balter

1
Я відчуваю, що це жахливий дизайн API. Читати підпис непросто ... Робити його a.caseInsensitiveCompare(b, comparing: .orderedSame)було б читабельніше ...
Мед,

25
if a.lowercaseString == b.lowercaseString {
    //Strings match
}

2
Чистий Свіфт - шлях сюди. Не потрібно фундаменту.
Олександр - Поновити Моніку

2
Перетворювати регістр, а потім порівнювати неправильно. Див. Коментарі до запитання.
Джим Балтер

1
@JimBalter Я б не сказав, що це "неправильно", оскільки воно відповідає на приклад, наведений у запитанні OP. Для тих з нас, кому не потрібно підтримувати локалізацію, це набагато чистіше!
toddg 07

4
^ Ні, це неправильно. Те, що щось трапляється для одного прикладу, не має значення. Цей хак зовсім не "чистіший". Прийнята відповідь дає правильне, чисте рішення.
Джим Балтер

8

ПРАВИЛЬНИЙ ШЛЯХ:

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

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

Зверніть увагу: ComparisonResult.orderedSame також може бути записаний як .orderedSame скорочено.

ІНШІ СПОСОБИ:

a.

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

b.

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
Перетворити регістр, а потім порівняти неправильно. Див. Коментарі до запитання.
Джим Балтер

6

localizedCaseInsensitiveContains : Повертає, чи містить одержувач заданий рядок, виконуючи нечутливий до регістру пошук з урахуванням локалі

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

Відредаговано :

caseInsensitiveCompare : Повертає результат виклику порівняння (_: options :) з NSCaseInsensitiveSearch як єдиним варіантом.

if a.caseInsensitiveCompare(b) == .orderedSame {
    //returns true if a equals b (case insensitive)
}

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")
}

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 () як шаблон (але дозволяючи операнду бути необов’язковим). Ось ігровий майданчик, який я використовував для його складання (нове для Свіфта, тому відгуки більш ніж вітаються).

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

Ви можете просто написати своє Розширення рядка для порівняння лише за кілька рядків коду

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

Стрімкий 3

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

}

2
Це неправильно. Див. Коментарі до запитання.
Jim Balter

-1

Свіфт 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 все ще хороша, але ...
dfri

... розгляньте можливість користувальницької функції (або Stringрозширення) як помічника вище, ніж замінювати відповідність Stringшаблону за замовчуванням .
dfri

-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
Це не працює для деяких рядків на деяких мовах ... див. Коментарі до запитання та безліч правильних відповідей, деякі з яких - включаючи прийняту - передували вашим за роками.
Jim Balter

-2

Свіфт 3:

Ви також можете використовувати локалізоване нечутливе до регістру порівняння між двома рядками функції, і вона повертається Bool

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

if a.localizedCaseInsensitiveContains(b) {
    print("Identical")           
} else {
    print("Non Identical")
}

2
Ваше рішення неправильне. Розглянемо рядки "casha" та "Cash"
clarkcox3
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.