¿Cómo comparar dos cadenas ignorando mayúsculas y minúsculas en lenguaje Swift?


95

¿Cómo podemos comparar dos cadenas en caso de ignorar rápidamente? por ejemplo:

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

¿Existe algún método que devuelva verdadero si comparamos var a & var b


1
Puede convertir ambos a minúsculas antes de hacer la comparación.
Dino Tw

8
Solo para tener en cuenta que lowercaseStringeso se menciona en algunas respuestas fallará en algunos idiomas (Straße! = STRASSE por ejemplo)
Alladiniano

@Alladiniano, ¿cómo sugerirías hacerlo entonces? La mayoría de los ejemplos para resolver este problema muestran la conversión a mayúsculas o minúsculas.
Steve

5
@Steve Apple sugiere caseInsensitiveCompare:y en su localizedCaseInsensitiveCompare:lugar
Alladiniano

3
@Steve ¡Seguro! (puedes probar "Straße".localizedCaseInsensitiveCompare("STRASSE")- Recuerda importar Foundation)
Alladiniano

Respuestas:


13

Prueba esto:

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)

el resultado es el tipo de enumeración NSComparisonResult:

enum NSComparisonResult : Int {

    case OrderedAscending
    case OrderedSame
    case OrderedDescending
}

Entonces puede usar la declaración if:

if result == .OrderedSame {
    println("equal")
} else {
    println("not equal")
}

Si mal no recuerdo, los parámetros de rango y configuración regional son opcionales y pueden omitirse por completo.
Mick MacCallum

3
Sí, de hecho, quería mostrar el método completo con todos los parámetros.
Greg

Deberías tener la respuesta correcta aquí. Comparar cadenas no se trata solo de saber si son iguales o no
Mikael

181

Prueba esto :

Para vencejos mayores:

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

13
En Swift 3 necesitas usara.caseInsensitiveCompare(b) == ComparisonResult.orderedSame
azhidkov

2
Nota: caseInsensitiveCompare(_:)no está incluido en la biblioteca estándar de Swift, sino que es parte del Foundationmarco, por lo que requiere import Foundation.
chrisamanse

¿Hay alguna razón por la que esto sea mejor que a.lowercased() == b.lowercased()?
jowie

36

caseInsensitiveCompareMétodo de uso :

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

ComparisonResult le dice qué palabra viene antes que la otra en orden lexicográfico (es decir, cuál se acerca al principio de un diccionario). .orderedSamesignifica que las cadenas terminarían en el mismo lugar en el diccionario


que .orderedSamesignifica Los documentos solo dicen que los dos operandos son iguales . Pero, ¿por qué se usa aquí la palabra "orden"? ¿Hay una secuencia o algo así? ¿Y qué hace? El operando izquierdo es más pequeño que el operando derecho. ( .orderedAscending) significa para cadenas
Cariño

1
El resultado de @Honey Comparison le dice qué palabra viene antes que la otra en orden lexicográfico (es decir, cuál se acerca al principio de un diccionario). .orderedSamesignifica que las cadenas terminarían en el mismo lugar en el diccionario.
dasblinkenlight

1
@Honey .orderedSamees la abreviatura de ComparisonResult.orderSame... no es necesario que nombre el tipo ya que el compilador sabe que caseInsensitiveComparedevuelve un ComparisonResult. "Los dos operandos son iguales", son iguales según un orden específico ... claramente, "Efectivo" y "efectivo" no son valores de cadena idénticos. "¿Pero por qué se usa aquí la palabra 'orden'?" - porque es el resultado de una comparación ordenada. Los otros valores son orderedAscendingy orderedDescending... no es solo una cuestión de iguales o diferentes. En cuanto a "más pequeño": las cadenas son como números en una base grande.
Jim Balter

1
Siento que este es un diseño de API terrible. La firma no es fácil de leer ... Hacerla a.caseInsensitiveCompare(b, comparing: .orderedSame)habría sido más legible ...
Cariño

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

2
Pure Swift es el camino a seguir aquí. No necesita base.
Alexander - Reincorporación a Monica

2
Convertir el caso y luego comparar es incorrecto. Vea los comentarios debajo de la pregunta.
Jim Balter

1
@JimBalter No diría que está "mal" ya que responde al ejemplo dado en la pregunta del OP. Para aquellos de nosotros que no necesitamos apoyar la localización, ¡esto es mucho más limpio!
toddg

4
^ No, está mal. Que algo suceda que funcione, por ejemplo, es irrelevante. Este truco no es "más limpio" en absoluto. La respuesta aceptada da la solución correcta y limpia.
Jim Balter

8

MANERA CORRECTA:

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

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

Tenga en cuenta: ComparisonResult.orderedSame también se puede escribir como .orderedSame en forma abreviada.

OTRAS MANERAS:

a.

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

si.

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

C.

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

7

Podría simplemente rodar el suyo:

func equalIgnoringCase(a:String, b:String) -> Bool {
    return a.lowercaseString == b.lowercaseString
}

3
Convertir el caso y luego comparar es incorrecto. Vea los comentarios debajo de la pregunta.
Jim Balter

6

localizedCaseInsensitiveContains : Devuelve si el receptor contiene una cadena determinada mediante la realización de una búsqueda que no distingue entre mayúsculas y minúsculas y que reconoce la configuración regional.

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

Editado :

caseInsensitiveCompare : Devuelve el resultado de invocar compare (_: options :) con NSCaseInsensitiveSearch como única opción.

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

1
La pregunta tiene que ver con la comparación, no con la contención.
Jim Balter

Si "a contiene b" y "b contiene a" , son iguales. Por tanto, esta es sin duda una posible solución, aunque no sea la más eficaz.
Philipp Maurer

1

También puede poner todas las letras en mayúsculas (o minúsculas) y ver si son iguales.

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

Esto hará que ambas variables sean ”CASH” sean iguales.

También puedes hacer una Stringextensión

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

if "Something ELSE".equalsIgnoreCase("something Else"){
  print("TRUE")
}

3
Convertir el caso y luego comparar es incorrecto. Vea los comentarios debajo de la pregunta.
Jim Balter

1

Ejemplo de comparación de números de teléfono; usando 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, fui por la ruta de extensión String usando caseInsensitiveCompare () como plantilla (pero permitiendo que el operando sea opcional). Aquí está el campo de juegos que solía armar (nuevo en Swift, así que los comentarios son más que bienvenidos).

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
Puede usar en .orderedSamelugar de ComparisonResult.orderedSame.
Jim Balter

0

Puede escribir su extensión de cadena para comparar en solo unas pocas líneas de código

extension String {

    func compare(_ with : String)->Bool{
        return self.caseInsensitiveCompare(with) == .orderedSame
    } 
}

0

Para Swift 5 Ignorando el caso y comparar dos cuerdas

var a = "cash"
var b = "Cash"
if(a.caseInsensitiveCompare(b) == .orderedSame){
     print("Ok")
}

-1

Swift 3

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

}

2
Esto está mal. Vea los comentarios debajo de la pregunta.
Jim Balter

-1

Swift 3 : puede definir su propio operador, por ejemplo ~=.

infix operator ~=

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

Que luego puedes probar en un parque infantil

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

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

test() // prints 'same'

No voté en contra de esto, pero tenga en cuenta que, en general, es una idea bastante mala, ya que el operador de coincidencia de patrones personalizados anterior tendrá prioridad sobre la coincidencia de patrones nativos que se usan normalmente cuando se comparan Stringinstancias entre sí (o con otros Stringliterales). Imagina let str = "isCAMELcase"que te cambian, con un caso de la siguiente manera:case "IsCamelCase": ... . Con el método anterior, esto casese ingresaría con éxito, lo que no se espera proveniente de la implementación estándar de libs de Stringcoincidencia de patrones. Sin embargo, una respuesta actualizada de Swift 3 sigue siendo buena, pero ...
dfri

... considere usar una función personalizada (o Stringextensión) como ayuda anterior en lugar de anular la Stringcoincidencia de patrones predeterminada .
dfri

-1
extension String
{
    func equalIgnoreCase(_ compare:String) -> Bool
    {
        return self.uppercased() == compare.uppercased()
    }
}

muestra de uso

print("lala".equalIgnoreCase("LALA"))
print("l4la".equalIgnoreCase("LALA"))
print("laLa".equalIgnoreCase("LALA"))
print("LALa".equalIgnoreCase("LALA"))

1
Esto no funciona para algunas cadenas en algunos idiomas ... vea los comentarios debajo de la pregunta y las muchas respuestas correctas, algunas de las cuales, incluida la aceptada, precedieron a la suya por años.
Jim Balter

-2

Swift 3:

También puede utilizar la comparación localizada que no distingue entre mayúsculas y minúsculas entre la función de dos cadenas y devuelve Bool

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

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

2
Tu solución es incorrecta. Considere las cadenas "casha" y "Cash"
clarkcox3
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.