【问题标题】:Swift: Sort array of objects alphabeticallySwift:按字母顺序对对象数组进行排序
【发布时间】:2014-12-30 10:25:02
【问题描述】:

我有这个:

class Movies {
  Name:String
  Date:Int
}

和 [电影] 数组。如何按名称按字母顺序对数组进行排序?我试过了:

movieArr = movieArr.sorted{ $0 < $1 }

movieArr = sorted(movieArr)

但这不起作用,因为我没有访问电影的名称属性。

【问题讨论】:

    标签: ios arrays swift sorting


    【解决方案1】:

    由于未能使用基于区域设置的比较进行排序,这些答案中的大多数都是错误的。看localizedStandardCompare()

    【讨论】:

      【解决方案2】:

      在传递给sort 的闭包中,比较要排序的属性。像这样:

      movieArr.sorted { $0.name < $1.name }
      

      或在您想要绕过案例的情况下使用以下内容:

      movieArr.sorted { $0.name.lowercased() < $1.name.lowercased() }
      

      旁注:通常只有类型以大写字母开头;我建议使用namedate,而不是NameDate


      例如,在操场上:

      class Movie {
          let name: String
          var date: Int?
      
          init(_ name: String) {
              self.name = name
          }
      }
      
      var movieA = Movie("A")
      var movieB = Movie("B")
      var movieC = Movie("C")
      
      let movies = [movieB, movieC, movieA]
      let sortedMovies = movies.sorted { $0.name < $1.name }
      sortedMovies
      

      sortedMovies 将按[movieA, movieB, movieC] 的顺序排列

      Swift5 更新

      channelsArray = channelsArray.sorted { (channel1, channel2) -> Bool in
                  let channelName1 = channel1.name
                  let channelName2 = channel2.name
                  return (channelName1.localizedCaseInsensitiveCompare(channelName2) == .orderedAscending)
      

      【讨论】:

      • 谢谢,我刚开始接触Swift,还不知道闭包的使用。
      • 使用 movies.sort 而不是 movies.sorted @Mike S
      • 感谢您的解释。改进了我的编辑,应该没问题,请看看:)
      • 当心,这在对可能大写也可能不大写的字符串进行排序时不起作用。比较.lowercaseString会解决这个问题。
      • @EricAya 注意它在 Swift 3 中又是 sorted :D。
      【解决方案3】:
      *import Foundation
      import CoreData
      
      
      extension Messages {
      
          @nonobjc public class func fetchRequest() -> NSFetchRequest<Messages> {
              return NSFetchRequest<Messages>(entityName: "Messages")
          }
      
          @NSManaged public var text: String?
          @NSManaged public var date: Date?
          @NSManaged public var friends: Friends?
      
      }
      
          //here arrMessage is the array you can sort this array as under bellow 
      
          var arrMessages = [Messages]()
      
          arrMessages.sort { (arrMessages1, arrMessages2) -> Bool in
                     arrMessages1.date! > arrMessages2.date!
          }*
      

      【讨论】:

        【解决方案4】:

        排序数组 斯威夫特 4.2

        arrayOfRaces = arrayOfItems.sorted(by: { ($0["raceName"] as! String) < ($1["raceName"] as! String) })
        

        【讨论】:

          【解决方案5】:
          let sortArray =  array.sorted(by: { $0.name.lowercased() < $1.name.lowercased() })
          

          【讨论】:

          • 经过长时间的尝试后,添加 .lowercased() 对我有用。我不明白为什么,因为所有文本都是小写的。
          • 当使用 lowercased() 时会将所有名称更改为小写以正确排序:)
          【解决方案6】:

          使用 Swift 3,您可以选择以下方法之一来解决您的问题。


          1。将sorted(by:​) 与不符合Comparable 协议的Movie 类一起使用

          如果您的Movie 类不符合Comparable 协议,您必须在闭包中指定您希望使用Array 的sorted(by:​) 方法的属性。

          Movie类声明:

          import Foundation
          
          class Movie: CustomStringConvertible {
          
              let name: String
              var date: Date
              var description: String { return name }
          
              init(name: String, date: Date = Date()) {
                  self.name = name
                  self.date = date
              }
          
          }
          

          用法:

          let avatarMovie = Movie(name: "Avatar")
          let titanicMovie = Movie(name: "Titanic")
          let piranhaMovie = Movie(name: "Piranha II: The Spawning")
          
          let movies = [avatarMovie, titanicMovie, piranhaMovie]
          let sortedMovies = movies.sorted(by: { $0.name < $1.name })
          // let sortedMovies = movies.sorted { $0.name < $1.name } // also works
          
          print(sortedMovies)
          
          /*
          prints: [Avatar, Piranha II: The Spawning, Titanic]
          */
          

          2。将sorted(by:​) 与符合Comparable 协议的Movie 类一起使用

          但是,通过使您的 Movie 类符合 Comparable 协议,当您想使用 Array 的 sorted(by:​) 方法时,您可以拥有非常简洁的代码。

          Movie类声明:

          import Foundation
          
          class Movie: CustomStringConvertible, Comparable {
          
              let name: String
              var date: Date
              var description: String { return name }
          
              init(name: String, date: Date = Date()) {
                  self.name = name
                  self.date = date
              }
          
              static func ==(lhs: Movie, rhs: Movie) -> Bool {
                  return lhs.name == rhs.name
              }
          
              static func <(lhs: Movie, rhs: Movie) -> Bool {
                  return lhs.name < rhs.name
              }
          
          }
          

          用法:

          let avatarMovie = Movie(name: "Avatar")
          let titanicMovie = Movie(name: "Titanic")
          let piranhaMovie = Movie(name: "Piranha II: The Spawning")
          
          let movies = [avatarMovie, titanicMovie, piranhaMovie]
          let sortedMovies = movies.sorted(by: { $0 < $1 })
          // let sortedMovies = movies.sorted { $0 < $1 } // also works
          // let sortedMovies = movies.sorted(by: <) // also works
          
          print(sortedMovies)
          
          /*
           prints: [Avatar, Piranha II: The Spawning, Titanic]
           */
          

          3。将sorted() 与符合Comparable 协议的Movie 类一起使用

          通过使您的Movie 类符合Comparable 协议,您可以使用Array 的sorted() 方法作为sorted(by:​) 的替代方法。

          Movie类声明:

          import Foundation
          
          class Movie: CustomStringConvertible, Comparable {
          
              let name: String
              var date: Date
              var description: String { return name }
          
              init(name: String, date: Date = Date()) {
                  self.name = name
                  self.date = date
              }
          
              static func ==(lhs: Movie, rhs: Movie) -> Bool {
                  return lhs.name == rhs.name
              }
          
              static func <(lhs: Movie, rhs: Movie) -> Bool {
                  return lhs.name < rhs.name
              }
          
          }
          

          用法:

          let avatarMovie = Movie(name: "Avatar")
          let titanicMovie = Movie(name: "Titanic")
          let piranhaMovie = Movie(name: "Piranha II: The Spawning")
          
          let movies = [avatarMovie, titanicMovie, piranhaMovie]
          let sortedMovies = movies.sorted()
          
          print(sortedMovies)
          
          /*
           prints: [Avatar, Piranha II: The Spawning, Titanic]
           */
          

          【讨论】:

          • 嘿,有什么区别吗?在第 2 和第 3 之间(movies.sorted(by: &lt;)movies.sorted() 除外)?
          • sorted(by:)sorted() 是两种不同的方法。您可以使用array.sorted() 作为array.sorted(by: &lt;) 的替代品。
          • 是的,只是在类定义的情况下询问我们是否需要更改任何内容?我的意思是,我们可以为sorted(by:)sorted() 定义相同的类吗?
          • 是的,你可以拥有你的类/结构的相同实现,在任何情况下都必须符合Comparable 协议。
          • 当我按升序排列时,我有带有 customObject 的数组,它没有以正确的方式短路。 "1" "14""28""31""4""42""49"
          【解决方案7】:

          对于那些使用 Swift 3 的人来说,接受答案的等效方法是:

          movieArr.sorted { $0.Name < $1.Name }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2019-06-15
            • 1970-01-01
            • 1970-01-01
            • 2013-11-02
            • 1970-01-01
            • 2021-12-28
            • 2018-12-03
            相关资源
            最近更新 更多