วิธีเปรียบเทียบสองสตริงโดยไม่สนใจตัวพิมพ์เล็กและใหญ่ในภาษา Swift


97

เราจะเปรียบเทียบสองสตริงในกรณีที่ไม่สนใจอย่างรวดเร็วได้อย่างไร สำหรับเช่น:

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

มีวิธีใดบ้างที่จะคืนค่าจริงถ้าเราเปรียบเทียบ var a & var b


1
คุณสามารถแปลงทั้งสองเป็นตัวพิมพ์เล็กก่อนทำการเปรียบเทียบ
Dino Tw

9
โปรดทราบว่าlowercaseStringที่กล่าวถึงในบางคำตอบจะล้มเหลวในบางภาษา (เช่นStraße! = STRASSE)
Alladinian

@Alladinian คุณจะแนะนำให้ทำอย่างไร ตัวอย่างส่วนใหญ่ในการแก้ปัญหานี้แสดงการแปลงเป็นตัวพิมพ์ใหญ่ทั้งหมดหรือตัวพิมพ์เล็กทั้งหมด?
Steve

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:

enum NSComparisonResult : Int {

    case OrderedAscending
    case OrderedSame
    case OrderedDescending
}

ดังนั้นคุณสามารถใช้คำสั่ง if:

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

ถ้าฉันจำได้ถูกต้องพารามิเตอร์ range และ locale เป็นทางเลือกและสามารถละเว้นได้ทั้งหมด
Mick MacCallum

3
ใช่ฉันต้องการแสดงวิธีการทั้งหมดพร้อมพารามิเตอร์ทั้งหมด
Greg

คุณควรมีคำตอบที่ถูกต้องที่นี่ การเปรียบเทียบสตริงไม่ใช่แค่การรู้ว่ามันเท่ากันหรือไม่เท่านั้น
มิคาเอล

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

13
ใน Swift 3 คุณต้องใช้a.caseInsensitiveCompare(b) == ComparisonResult.orderedSame
azhidkov

3
หมายเหตุ: caseInsensitiveCompare(_:)ไม่รวมอยู่ในห้องสมุดมาตรฐานสวิฟท์ค่อนข้างจะเป็นส่วนหนึ่งของกรอบจึงต้องFoundation import Foundation
chrisamanse

มีเหตุผลอะไรที่ดีไปกว่านี้a.lowercased() == b.lowercased()?
jowie

@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) mean for strings
น้ำผึ้ง

1
@ ผลการเปรียบเทียบน้ำผึ้งจะบอกคุณว่าคำใดมาเร็วกว่าคำอื่น ๆ ในลำดับพจนานุกรม (กล่าวคือคำใดเข้ามาใกล้ด้านหน้าของพจนานุกรม) .orderedSameหมายความว่าสตริงจะจบลงที่จุดเดียวกันในพจนานุกรม
Sergey Kalinichenko

1
@Honey .orderedSameย่อมาจากComparisonResult.orderSame... คุณไม่จำเป็นต้องตั้งชื่อประเภทเนื่องจากคอมไพเลอร์รู้ว่าcaseInsensitiveCompareส่งกลับไฟล์ComparisonResult. "ตัวถูกดำเนินการสองตัวเท่ากัน" - มีค่าเท่ากันตามลำดับที่ระบุ ... ชัดเจน "เงินสด" และ "เงินสด" ไม่ใช่ค่าสตริงที่เหมือนกัน "แต่ทำไมถึงใช้คำว่า 'สั่ง' ที่นี่? - เนื่องจากเป็นผลมาจากการเปรียบเทียบตามลำดับ ค่าอื่น ๆ คือorderedAscendingและorderedDescending... ไม่ใช่แค่คำถามว่าเหมือนหรือต่างกัน สำหรับ "เล็กกว่า": สตริงเป็นเหมือนตัวเลขในฐานขนาดใหญ่
Jim Balter

1
ฉันรู้สึกว่านี่เป็นการออกแบบ API ที่แย่มาก ลายเซ็นไม่ง่ายที่จะอ่านแล้ว ... ทำมันa.caseInsensitiveCompare(b, comparing: .orderedSame)จะได้รับการอ่านได้มากขึ้น ...
น้ำผึ้ง

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

2
Pure Swift เป็นวิธีที่จะไปที่นี่ ไม่จำเป็นต้องรองพื้น
Alexander - Reinstate Monica

2
การแปลงกรณีแล้วเปรียบเทียบผิด ดูความคิดเห็นใต้คำถาม
Jim Balter

1
@JimBalter ฉันจะไม่บอกว่ามัน "ผิด" เพราะมันตอบตัวอย่างที่ให้ไว้ในคำถามของ OP สำหรับพวกเราที่ไม่จำเป็นต้องรองรับการแปลมันจะสะอาดกว่านี้มาก!
Toddg

4
^ ไม่มันผิด สิ่งที่เกิดขึ้นกับตัวอย่างหนึ่งไม่เกี่ยวข้อง แฮ็คนี้ไม่ "สะอาดกว่า" เลย คำตอบที่ยอมรับจะให้วิธีแก้ปัญหาที่ถูกต้องและสะอาด
Jim Balter

8

วิธีที่ถูกต้อง:

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

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

โปรดทราบ: ComparisonResult.orderedSame ยังสามารถเขียนเป็น. orderSame ในชวเลขได้

ทางอื่น:

ก.

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

ข.

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

ค.

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

7

สามารถม้วนของคุณเอง:

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

3
การแปลงกรณีแล้วเปรียบเทียบผิด ดูความคิดเห็นใต้คำถาม
Jim Balter

7

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
คำถามเกี่ยวกับการเปรียบเทียบไม่ใช่การกักกัน
Jim Balter

ถ้า"a มี b"และ"b มี a"จะมีค่าเท่ากัน ดังนั้นนี่เป็นวิธีแก้ปัญหาที่เป็นไปได้อย่างแน่นอนแม้ว่าอาจจะไม่ใช่วิธีที่มีประสิทธิภาพมากที่สุดก็ตาม
Philipp Maurer

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
การแปลงกรณีแล้วเปรียบเทียบผิด ดูความคิดเห็นใต้คำถาม
Jim Balter

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.
Jim Balter

0

คุณสามารถเขียน String Extension เพื่อเปรียบเทียบได้ในโค้ดไม่กี่บรรทัด

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 : ~=คุณสามารถกำหนดผู้ประกอบการของคุณเองเช่น

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จะถูกป้อนสำเร็จซึ่งไม่คาดว่าจะมาจากการใช้ libs มาตรฐานของการ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
สิ่งนี้ใช้ไม่ได้กับบางสตริงในบางภาษา ... ดูความคิดเห็นใต้คำถามและคำตอบที่ถูกต้องหลายคำตอบซึ่งบางส่วนรวมถึงสตริงที่ได้รับการยอมรับนำหน้าคุณเป็นปี
Jim Balter

-2

Swift 3:

คุณยังสามารถใช้การเปรียบเทียบแบบไม่คำนึงถึงตัวพิมพ์เล็กและตัวพิมพ์ใหญ่ที่แปลแล้วระหว่างฟังก์ชันสองสตริงและส่งกลับ Bool

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

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

2
โซลูชันของคุณไม่ถูกต้อง พิจารณาสตริง "casha" และ "Cash"
clarkcox3
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.