1

I am currently having two issues with two different arrays:

1) In my Xcode project I have an array that contains users that is used for a tableView. Each user is part of a class called 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
        }
    }

When I look for an object, it is possible that 1 user can have the same object twice so it appends that user twice to the array and when the array is put to the tableView, the user shows up twice. How do I take out the duplicate user based on their userObjectID? I believe I will have to sort it out after getting the data, but I am not sure how to do this.

2) The second problem is sorting another one of my arrays that contains a class by date before it is loaded to the tableView. Here is my class:

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

I will like to sort the array by the 'date' that is in each 'Object' but I am not sure how to do this.

Any guidance on both or 1 of these issues will be greatly appreciated. Thank you in advance.

ap123
  • 916
  • 1
  • 8
  • 22
  • 1
    You need to make your class conform to Equatable protocol. You should also make it conformant to Hashable to be able to use your class with a Set. – Leo Dabus Oct 24 '17 at 02:49
  • Also, since each instance of the class represents **a single user**, consider renaming your class to `User`. Other people reading your code (and yourself in the future) will thank you ;) – Nicolas Miari Oct 24 '17 at 02:53
  • And don't make all your properties optionals. Only make a property optional if it can really be nil or can't be initialized at your init. And make them all constants and provide the required initializer. – Leo Dabus Oct 24 '17 at 02:55
  • Also looks like you are not subclassing anything so you should consider using a struct. – Leo Dabus Oct 24 '17 at 03:00
  • If you need to sort your objects you should make them also conform to Comparable protocol – Leo Dabus Oct 24 '17 at 03:01
  • @LeoDabus I am a beginner coder and not sure what you mean. How should I go about removing the duplicate user in an array of users and sorting my array of Objects by date? – ap123 Oct 24 '17 at 06:30
  • `class User: Hashable, Comparable, CustomStringConvertible { let id : Int let fullname : String var date: Date let username : String var hashValue: Int { return id } var description: String { return String(id) } init(_ id: Int, fullname: String, date: Date, username: String) { self.id = id self.fullname = fullname self.date = date self.username = username } static func ==(lhs: User, rhs: User) -> Bool { return lhs.id == rhs.id } static func <(lhs: User, rhs: User) -> Bool { return lhs.date < rhs.date }}` – Leo Dabus Oct 24 '17 at 06:40
  • or even better make it a struct `struct User: Hashable, Comparable, CustomStringConvertible { let id: Int let fullname: String var date: Date let username: String var hashValue: Int { return id } var description: String { return String(id) } static func ==(lhs: User, rhs: User) -> Bool { return lhs.id == rhs.id } static func <(lhs: User, rhs: User) -> Bool { return lhs.date < rhs.date } }` – Leo Dabus Oct 24 '17 at 06:42
  • to remove duplicates you can use a set. Note that you will lose the array order or use this extension orderedSet from this answer I posted here https://stackoverflow.com/questions/25738817/removing-duplicate-elements-from-an-array/34712330?s=1|30.4424#34712330 – Leo Dabus Oct 24 '17 at 06:44
  • @LeoDabus How exactly should I sort by array that contains the class "Objects" by the date of each Object? I try doing the array.sort but I am not sure how to do it – ap123 Nov 01 '17 at 02:38

3 Answers3

1
  1. In order to remove the duplicates you could use a SET or just do something like this:

Creating and using this function:

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

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

    return result
}

2.In order to sort the array you could do:

array.sort { 
    $0.date.compare($1.date) == .orderedDescending // it depends the order you want to use
} 
Gabriel Goncalves
  • 5,132
  • 3
  • 25
  • 34
0
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})
Yongjoon
  • 104
  • 1
  • 4
  • `map {$0}` is pointless. And `Date` conforms to `Comparable` protocol since Swift 3 (at least). Why not simply `let results = arr.sorted { $0.date < $1.date }` – Leo Dabus Oct 24 '17 at 04:57
  • btw If it already conforms to Hashable, adding Equatable is redundant. – Leo Dabus Oct 24 '17 at 05:29
  • Also you should change your object ID type to Int – Leo Dabus Oct 24 '17 at 05:31
  • And to be able to print your Users, make it conform to CustomStringConvertible and implement a description property. This way you don't need to use map when printing postsSet `Set` or results `[Users]`. – Leo Dabus Oct 24 '17 at 05:32
  • this did not work, it only set the first newest object at the top of the tableview. And every time I refresh a different object is at the bottom of the newest one, meaning the other rows are not in order by date. How can I fix this? – ap123 Nov 01 '17 at 02:34
0
  1. let unique = Set(allUsers)

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

Adam Eri
  • 889
  • 7
  • 13