【问题标题】:Deleting Duplicates from an Array of Classes and Sorting An Array By Date从类数组中删除重复项并按日期对数组进行排序
【发布时间】:2017-10-24 02:47:00
【问题描述】:

我目前对两个不同的数组有两个问题:

1) 在我的 Xcode 项目中,我有一个包含用于 tableView 的用户的数组。每个用户都是名为 users 的类的一部分:

class Users {
        let userObjectID : String
        let profilePhoto : UIImage
        let fullname : String
        let username : String

        init(userObjectID : String, profilePhoto : UIImage, fullname : String, username : String) {
            self.userObjectID = userObjectID
            self.profilePhoto = profilePhoto
            self.fullname = fullname
            self.username = username
        }
    }

当我查找一个对象时,有可能 1 个用户可以拥有相同的对象两次,因此它将该用户两次附加到数组中,当数组放入 tableView 时,用户出现两次。如何根据用户的 userObjectID 取出重复的用户?我相信我得到数据后必须整理一下,但我不知道该怎么做。

2) 第二个问题是在加载到 tableView 之前按日期对包含类的另一个数组进行排序。这是我的课:

class Object {
    var id: String?
    var date: Date? //want to use for tableView order
    var owner : String?
    var ownerFullname : String?
    var ownerProfilePic : UIImage?
    var name: String?
}

我想按每个“对象”中的“日期”对数组进行排序,但我不知道该怎么做。

我们将不胜感激任何有关这两个或其中一个问题的指导。提前谢谢您。

【问题讨论】:

  • 你需要让你的类符合 Equatable 协议。您还应该使其符合 Hashable 以便能够将您的类与 Set 一起使用。
  • 另外,由于类的每个实例都代表一个用户,请考虑将您的类重命名为User。其他阅读您的代码的人(以及未来的您自己)会感谢您;)
  • 不要将所有属性都设为可选。仅当属性确实可以为 nil 或无法在您的初始化时初始化时才将其设为可选。并将它们全部设为常量并提供所需的初始化程序。
  • 看起来你没有继承任何东西,所以你应该考虑使用结构。
  • 如果你需要对你的对象进行排序,你应该让它们也符合 Comparable 协议

标签: arrays swift class


【解决方案1】:
  1. 要删除重复项,您可以使用 SET 或执行以下操作:

创建和使用这个函数:

func removeDuplicates(_ array: [User]) -> [User] {
    var result: User = []

    for user in users {
        if result.contains(user) == false {
            result.append(user)
        }
    }

    return result
}

2.为了对数组进行排序,您可以这样做:

array.sort { 
    $0.date.compare($1.date) == .orderedDescending // it depends the order you want to use
} 

【讨论】:

  • 您的 originals 对象的类型是什么?如果不符合 Hashable 协议,则无法创建一组自定义类或结构。
  • 不符合Comparable协议的也不能排序
  • 如果 User 不符合 Equatable 则不能使用 contains 方法。
【解决方案2】:
class Users : Hashable, Equatable {
  let userObjectID : String
  let fullname : String
   var date: Date
  let username : String

  var hashValue: Int { get{
    return Int(self.userObjectID)!
    }
  }
  init(_ userObjectID : String, fullname : String, date:Date,  username : String) {
    self.userObjectID = userObjectID
    self.fullname = fullname
    self.date = date
    self.username = username
  }

  static func ==(lhs: Users, rhs: Users) -> Bool {
    return lhs.userObjectID == rhs.userObjectID
  }
}

let u1 = Users("1", fullname: "ssd", date: Date(), username: "3232")
let u2 = Users("2", fullname: "ssd", date: Date().addingTimeInterval(10), username: "3232")
let u3 = Users("2", fullname: "ssd", date: Date().addingTimeInterval(10), username: "3232")
let u4 = Users("2", fullname: "ssd", date: Date().addingTimeInterval(10), username: "3232")
let u5 = Users("5", fullname: "ssd", date: Date().addingTimeInterval(10), username: "3232")
let u6 = Users("6", fullname: "ssd", date: Date().addingTimeInterval(-100), username: "3232")

let arr = [u1, u2, u3, u4,u5,u6]

let postsSet = Set(arr)

print(postsSet.map{$0.userObjectID})


//date..
let results  = arr.map {$0}.sorted { (u1, u2) -> Bool in
    return Calendar.current.compare(u1.date, to: u2.date, toGranularity: .second) == .orderedSame
}

print(results.map{$0.userObjectID})

【讨论】:

  • map {$0} 毫无意义。并且 Date 符合 Comparable 协议,因为 Swift 3 (至少)。为什么不简单地let results = arr.sorted { $0.date < $1.date }
  • btw 如果已经符合 Hashable,添加 Equatable 是多余的。
  • 另外,您应该将对象 ID 类型更改为 Int
  • 为了能够打印您的用户,使其符合 CustomStringConvertible 并实现描述属性。这样打印postsSet Set<Users>或results [Users]时就不需要使用map了。
  • 这不起作用,它只将第一个最新的对象设置在 tableview 的顶部。每次我刷新一个不同的对象时,都在最新对象的底部,这意味着其他行不是按日期排序的。我该如何解决这个问题?
【解决方案3】:
  1. let unique = Set(allUsers)

  2. objects.sort { $0.date.compare($1.date) == .orderedDescending }

【讨论】:

    猜你喜欢
    • 2023-03-13
    • 2021-11-20
    • 1970-01-01
    • 2015-02-25
    • 2014-04-29
    • 2014-11-05
    • 2013-04-23
    • 2013-05-10
    • 2018-02-09
    相关资源
    最近更新 更多