use a Set
To use it, make your Post hashable and implement the ==
operator
import Foundation
class Post: Hashable, Equatable {
let id:UInt
let title:String
let date:NSDate
var hashValue: Int { get{
return Int(self.id)
}
}
init(id:UInt, title:String, date:NSDate){
self.id = id
self.title = title
self.date = date
}
}
func ==(lhs: Post, rhs: Post) -> Bool {
return lhs.id == rhs.id
}
let posts = [Post(id: 11, title: "sadf", date: NSCalendar.currentCalendar().dateFromComponents({let c = NSDateComponents(); c.day = 1; c.month = 1; c.year = 2016; return c}())!),
Post(id: 33, title: "sdfr", date: NSCalendar.currentCalendar().dateFromComponents({let c = NSDateComponents(); c.day = 3; c.month = 1; c.year = 2016; return c}())!),
Post(id: 22, title: "sdfr", date: NSCalendar.currentCalendar().dateFromComponents({let c = NSDateComponents(); c.day = 1; c.month = 12; c.year = 2015; return c}())!),
Post(id: 22, title: "sdfr", date: NSCalendar.currentCalendar().dateFromComponents({let c = NSDateComponents(); c.day = 1; c.month = 12; c.year = 2015; return c}())!)]
Create set from array with duplicates
let postsSet = Set(posts)
This is unordered, create a new array, apply order.
let uniquePosts = Array(postsSet).sort { (p1, p2) -> Bool in
return p1.date.timeIntervalSince1970 < p2.date.timeIntervalSince1970
}
Instead of making your Post
model hashable, you could also use a wrapper class. This wrapper class would use the post objects property to calculate the hash and equality.
this wrapper could be configurable through closure:
class HashableWrapper<T>: Hashable {
let object: T
let equal: (obj1: T,obj2: T) -> Bool
let hash: (obj: T) -> Int
var hashValue:Int {
get {
return self.hash(obj: self.object)
}
}
init(obj: T, equal:(obj1: T, obj2: T) -> Bool, hash: (obj: T) -> Int) {
self.object = obj
self.equal = equal
self.hash = hash
}
}
func ==<T>(lhs:HashableWrapper<T>, rhs:HashableWrapper<T>) -> Bool
{
return lhs.equal(obj1: lhs.object,obj2: rhs.object)
}
The Post could be simply
class Post {
let id:UInt
let title:String
let date:NSDate
init(id:UInt, title:String, date:NSDate){
self.id = id
self.title = title
self.date = date
}
}
Let's create some post as before
let posts = [
Post(id: 3, title: "sadf", date: NSCalendar.currentCalendar().dateFromComponents({let c = NSDateComponents(); c.day = 1; c.month = 1; c.year = 2016; return c}())!),
Post(id: 1, title: "sdfr", date: NSCalendar.currentCalendar().dateFromComponents({let c = NSDateComponents(); c.day = 3; c.month = 1; c.year = 2016; return c}())!),
Post(id: 2, title: "sdfr", date: NSCalendar.currentCalendar().dateFromComponents({let c = NSDateComponents(); c.day = 1; c.month = 12; c.year = 2015; return c}())!),
Post(id: 2, title: "sdfr", date: NSCalendar.currentCalendar().dateFromComponents({let c = NSDateComponents(); c.day = 1; c.month = 12; c.year = 2015; return c}())!),
Post(id: 1, title: "sdfr", date: NSCalendar.currentCalendar().dateFromComponents({let c = NSDateComponents(); c.day = 3; c.month = 1; c.year = 2016; return c}())!)
]
Now we create wrapper objects for every post with closure to determine equality and the hash. And we create the set.
let wrappers = posts.map { (p) -> HashableWrapper<Post> in
return HashableWrapper<Post>(obj: p, equal: { (obj1, obj2) -> Bool in
return obj1.id == obj2.id
}, hash: { (obj) -> Int in
return Int(obj.id)
})
}
let s = Set(wrappers)
Now we extract the wrapped objects and sort it by date.
let objects = s.map { (w) -> Post in
return w.object
}.sort { (p1, p2) -> Bool in
return p1.date.timeIntervalSince1970 > p2.date.timeIntervalSince1970
}
and
print(objects.map{$0.id})
prints
[1, 3, 2]