【问题标题】:Swift FullName Array SortSwift 全名数组排序
【发布时间】:2021-12-21 16:56:24
【问题描述】:

对可选的“全名”字符串数组进行排序的最佳方法是什么

更新:很抱歉..我忘记了最重要的一点。需要按姓、名、单名排序,nil的在上

let unordered:[String?] = [
"Zach Appletree",
"Nancy Crabtree",
"Bill",
nil,
"Bonny Appletree",
"Zach Johnson",
"Paul Brandon"
]

let sortedArray = unordered.sorted(by: { } )

【问题讨论】:

  • 你想要的输出是什么?按姓氏字母顺序搜索?按字母顺序排列的名字? nil 项目在哪里?它们是被过滤掉了,还是从头/尾开始?
  • 如果您的全名也可以只是名字(如您指定的那样),并且可能是“LastName FirstName”(例如“刘建国”,其中刘是姓氏),那么您只能处理它们就像 strings 一样,并按字母顺序排序,因为你不能假设任何事情。唯一的问题是你是否想在我们的外面住 nils(即是否使用 `compactMap)。
  • 试试这样的:let sortedArray = unordered.compactMap{$0}.sorted(by: { $0 < $1})

标签: arrays swift


【解决方案1】:

使用 compactMap(_:)

https://developer.apple.com/documentation/swift/sequence/2950916-compactmap

let unordered:[String?] = [
        "Zach Appletree",
        "Nancy Crabtree",
        "Bill",
        nil,
        "Bonny Appletree",
        "Zach Johnson",
        "Paul Brandon"
        ]
        
let sortedArray = unordered.compactMap { $0 }.sorted()
print(sortedArray)

【讨论】:

    【解决方案2】:

    PersonNameComponents 不是 Comparable,除非您自己定义一致性。

    例如

    unordered
      .lazy
      .compactMap { $0.flatMap(PersonNameComponentsFormatter().personNameComponents) }
      .sorted()
    
    extension PersonNameComponents: Comparable {
      public static func < (components0: Self, components1: Self) -> Bool {
        var fallback: Bool {
          [\PersonNameComponents.givenName, \.middleName].contains {
            Optional(components0[keyPath: $0], components1[keyPath: $0])
              .map { $0.lowercased().isLessThan($1.lowercased(), whenEqual: false) }
            ?? false
          }
        }
        
        switch (
          components0.givenName?.lowercased(), components0.familyName?.lowercased(),
          components1.givenName?.lowercased(), components1.familyName?.lowercased()
        ) {
        case let (
          _, familyName0?,
          _, familyName1?
        ):
          return familyName0.isLessThan(familyName1, whenEqual: fallback)
        case (
          _, let familyName0?,
          let givenName1?, nil
        ):
          return familyName0.isLessThan(givenName1, whenEqual: fallback)
        case (
          let givenName0?, nil,
          _, let familyName1?
        ):
          return givenName0.isLessThan(familyName1, whenEqual: fallback)
        default:
          return fallback
        }
      }
    }
    
    public extension Comparable {
      /// Like `<`, but with a default for the case when `==` evaluates to `true`.
      func isLessThan(
        _ comparable: Self,
        whenEqual default: @autoclosure () -> Bool
      ) -> Bool {
        self == comparable
        ? `default`()
        : self < comparable
      }
    }
    
    public extension Optional {
      /// Exchange two optionals for a single optional tuple.
      /// - Returns: `nil` if either tuple element is `nil`.
      init<Wrapped0, Wrapped1>(_ optional0: Wrapped0?, _ optional1: Wrapped1?)
      where Wrapped == (Wrapped0, Wrapped1) {
        self = .init((optional0, optional1))
      }
    
      /// Exchange two optionals for a single optional tuple.
      /// - Returns: `nil` if either tuple element is `nil`.
      init<Wrapped0, Wrapped1>(_ optionals: (Wrapped0?, Wrapped1?))
      where Wrapped == (Wrapped0, Wrapped1) {
        switch optionals {
        case let (wrapped0?, wrapped1?):
          self = (wrapped0, wrapped1)
        default:
          self = nil
        }
      }
    }
    

    【讨论】:

    • 哇...永远不会想出那个...太好了!
    • 如果人名/全名在结构内部,这会变得多么复杂?所以一个数组:struct Passengers { var id: String var fullName: String?变量状态:字符串}
    • 我不知道如何衡量您的要求。但我也不知道你为什么不存储nameComponents: PersonNameComponents 而不是fullName: String
    • 不幸的是,它是来自 Realm DB 的数据,它来自 DB。这是一个现有结构,需要更改提取全名的方式。可以做到这一点,只是没有'现在它如何更改平面图,因为它是一个返回的结构 vs PersonNameComponents。如果我按照自己的方式进行操作,我只会将 FirstName、LastName 作为结构的一部分包含在内
    • 谢谢,Jessy,我将内部排序更改为使用 PersonNameComponets,结构数组现在已排序!再次感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-21
    • 2018-10-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多