【问题标题】:Sorting a String array and ignoring case对字符串数组进行排序并忽略大小写
【发布时间】:2015-09-06 00:32:05
【问题描述】:

如果字符串数组全部为小写或全部大写,则下面的代码适用于对字符串数组进行排序,但我想在排序时忽略大小写。我怎么能这样做?下面是一个自定义类的数组。

resultListArray.sort({ $0.fileName.compare($1.fileName) == NSComparisonResult.OrderedAscending })

【问题讨论】:

    标签: ios swift


    【解决方案1】:

    你可以使用String方法localizedCompare()

    更新: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"
    

    您还可以实现自己的自定义排序/排序方法:

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

    用法:

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


    要通过字符串属性对自定义对象进行排序,我们可以传递一个谓词以从元素中获取字符串,并在调用此方法时使用键路径:

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

    用法:

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

    【讨论】:

      【解决方案2】:

      这是应该使用的方法,旨在用于此目的:

      public func caseInsensitiveCompare(aString: String) -> NSComparisonResult
      

      在你的情况下:

      resultListArray.sort({ $0.fileName.caseInsensitiveCompare($1.fileName) == NSComparisonResult.OrderedAscending })
      

      【讨论】:

        【解决方案3】:
        var items = ["a","A","b","B","c","C","d","D"] 
        items = items.sorted(by: { (item1, item2) -> Bool in
             return item1.localizedCompare(item2) == .orderedAscending
        })
        

        【讨论】:

        • 您好,欢迎来到 SO。感谢您回复 Gary Dorman 的问题。您能否提供更多信息来回答您的问题?
        • 为什么不简单地 items.sort 呢? items = items.sorted 毫无意义。
        【解决方案4】:

        您可以将String 转换为小写,然后进行比较:

        array.sort{ $0.lowercaseString < $1.lowercaseString }
        

        【讨论】:

          【解决方案5】:

          这里是 an answer about overriding compareTo in Java 来更改 sort 订购东西的方式。如果将字符串转换为大写,然后比较它们会发生什么?

          【讨论】:

          • 我正在使用 Swift 编程。通常我可以将字符串转换为大写或小写,但这次不是一个选项。
          • 哦,抱歉。我误读了标签。看到这个问题,然后:stackoverflow.com/questions/31871395/…
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-05-13
          • 1970-01-01
          • 2013-01-31
          • 2015-10-10
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多