Sorting a String array and ignoring case

前端 未结 5 1784
眼角桃花
眼角桃花 2020-12-29 05:09

The code below works for sorting an array of strings if they are all lowercase or all uppercase but I want to ignore case when I sort. How could I do this? The following is

相关标签:
5条回答
  • 2020-12-29 05:17

    This is the method that should be used and is intended for this purpose:

    public func caseInsensitiveCompare(aString: String) -> NSComparisonResult
    

    In your case:

    resultListArray.sort({ $0.fileName.caseInsensitiveCompare($1.fileName) == NSComparisonResult.OrderedAscending })
    
    0 讨论(0)
  • 2020-12-29 05:27

    Here’s an answer about overriding compareTo in Java to change how sort orders things. What happens if you convert the strings to uppercase, then compare them?

    0 讨论(0)
  • 2020-12-29 05:30
    var items = ["a","A","b","B","c","C","d","D"] 
    items = items.sorted(by: { (item1, item2) -> Bool in
         return item1.localizedCompare(item2) == .orderedAscending
    })
    
    0 讨论(0)
  • 2020-12-29 05:32

    You can convert the String to lowercase and then compare it:

    array.sort{ $0.lowercaseString < $1.lowercaseString }
    
    0 讨论(0)
  • 2020-12-29 05:44

    You can use String method localizedCompare()

    update: Xcode 11.5 • Swift 5.2

    let array = ["def","Ghi","Abc" ]
    
    let sorted1 = array.sorted{$0.compare($1) == .orderedAscending} 
    print(sorted1)  // ["Abc", "Ghi", "def"] this is case SENSITIVE!
    
    let sorted2 = array.sorted{$0.localizedCompare($1) == .orderedAscending}
    print(sorted2) // ["Abc", "def", "Ghi"]
    
    
    // you can also use the String compare options parameter to give you more control when comparing your strings
    let sorted3 = array.sorted{$0.compare($1, options: .caseInsensitive) == .orderedAscending }
    print(sorted3)   // ["Abc", "def", "Ghi"]\n"
    
    // which can be simplifyed using the string method caseInsensitiveCompare
    let sorted4 = array.sorted{$0.caseInsensitiveCompare($1) == .orderedAscending}
    print(sorted4) // ["Abc", "def", "Ghi"]\n"
    
    // or localizedStandardCompare (case and diacritic insensitive)
    // This method should be used whenever file names or other strings are presented in lists and tables where Finder-like sorting is appropriate. The exact sorting behavior of this method is different under different locales and may be changed in future releases. This method uses the current locale.
    let array5 = ["Cafe B","Café C","Café A"]
    let sorted5 = array5.sorted { $0.localizedStandardCompare($1) == .orderedAscending }
    print(sorted5) // "["Café A", "Cafe B", "Café C"]\n"
    

    You can also implement your own custom sort/sorted methods:

    extension Collection where Element: StringProtocol {
        public func localizedSorted(_ result: ComparisonResult) -> [Element] {
            sorted { $0.localizedCompare($1) == result }
        }
        public func caseInsensitiveSorted(_ result: ComparisonResult) -> [Element] {
            sorted { $0.caseInsensitiveCompare($1) == result }
        }
        public func localizedCaseInsensitiveSorted(_ result: ComparisonResult) -> [Element] {
            sorted { $0.localizedCaseInsensitiveCompare($1) == result }
        }
        /// This method should be used whenever file names or other strings are presented in lists and tables where Finder-like sorting is appropriate. The exact sorting behavior of this method is different under different locales and may be changed in future releases. This method uses the current locale.
        public func localizedStandardSorted(_ result: ComparisonResult) -> [Element] {
            sorted { $0.localizedStandardCompare($1) == result }
        }
    }
    

    extension MutableCollection where Element: StringProtocol, Self: RandomAccessCollection {
        public mutating func localizedSort(_ result: ComparisonResult) {
            sort { $0.localizedCompare($1) == result }
        }
        public mutating func caseInsensitiveSort(_ result: ComparisonResult) {
            sort { $0.caseInsensitiveCompare($1) == result }
        }
        public mutating func localizedCaseInsensitiveSort(_ result: ComparisonResult) {
            sort { $0.localizedCaseInsensitiveCompare($1) == result }
        }
        /// This method should be used whenever file names or other strings are presented in lists and tables where Finder-like sorting is appropriate. The exact sorting behavior of this method is different under different locales and may be changed in future releases. This method uses the current locale.
        public mutating func localizedStandardSort(_ result: ComparisonResult) {
            sort { $0.localizedStandardCompare($1) == result }
        }
    }
    

    Usage:

    var array = ["def","Ghi","Abc" ]
    array.caseInsensitiveSort(.orderedAscending)
    array    // ["Abc", "def", "Ghi"]
    


    To sort a custom object by a string property we can pass a predicate to get the string from the element and use a keypath when calling this method:

    extension Collection {
        /// This method should be used whenever file names or other strings are presented in lists and tables where Finder-like sorting is appropriate. The exact sorting behavior of this method is different under different locales and may be changed in future releases. This method uses the current locale.
        public func localizedStandardSorted<T: StringProtocol>(by predicate: (Element) -> T, ascending: Bool = true) -> [Element] {
            sorted { predicate($0).localizedStandardCompare(predicate($1)) == (ascending ? .orderedAscending : .orderedDescending) }
        }
    }
    

    extension MutableCollection where Self: RandomAccessCollection {
        /// This method should be used whenever file names or other strings are presented in lists and tables where Finder-like sorting is appropriate. The exact sorting behavior of this method is different under different locales and may be changed in future releases. This method uses the current locale.
        public mutating func localizedStandardSort<T: StringProtocol>(by predicate: (Element) -> T, ascending: Bool = true) {
            sort { predicate($0).localizedStandardCompare(predicate($1)) == (ascending ? .orderedAscending : .orderedDescending) }
        }
    }
    

    Usage:

    struct File {
        let id: Int
        let fileName: String
    }
    

    var files: [File] = [.init(id: 2, fileName: "Steve"),
                         .init(id: 5, fileName: "Bruce"),
                         .init(id: 3, fileName: "alan")]
    
    let sorted = files.localizedStandardSorted(by: \.fileName)
    print(sorted)  // [File(id: 3, fileName: "alan"), File(id: 5, fileName: "Bruce"), File(id: 2, fileName: "Steve")]
    
    files.localizedStandardSort(by: \.fileName)
    print(files)  // [File(id: 3, fileName: "alan"), File(id: 5, fileName: "Bruce"), File(id: 2, fileName: "Steve")]
    
    0 讨论(0)
提交回复
热议问题