从自定义对象数组中删除重复项 Swift
Removing Duplicates From Array of Custom Objects Swift
我有一个自定义 class 定义如下:
class DisplayMessage : NSObject {
var id : String?
var partner_image : UIImage?
var partner_name : String?
var last_message : String?
var date : NSDate?
}
现在我有一个数组 myChats = [DisplayMessage]?
。 id
字段对于每个 DisplayMessage
对象都是唯一的。我需要检查我的数组并从中删除所有重复项,基本上确保数组中的所有对象都具有唯一的 id
。我已经看到一些使用 NSMutableArray
和 Equatable
的解决方案,但是我不确定如何在这里调整它们;我也知道 Array(Set(myChats))
但这似乎不适用于自定义对象数组。
您可以使用一组字符串来完成,如下所示:
var seen = Set<String>()
var unique = [DisplayMessage]
for message in messagesWithDuplicates {
if !seen.contains(message.id!) {
unique.append(message)
seen.insert(message.id!)
}
}
我们的想法是保留一组到目前为止我们已经看到的所有 ID,循环遍历所有项目,然后添加我们没有看到的 ID。
这是 return 基于给定键的唯一对象列表的数组扩展:
extension Array {
func unique<T:Hashable>(map: ((Element) -> (T))) -> [Element] {
var set = Set<T>() //the unique list kept in a Set for fast retrieval
var arrayOrdered = [Element]() //keeping the unique list of elements but ordered
for value in self {
if !set.contains(map(value)) {
set.insert(map(value))
arrayOrdered.append(value)
}
}
return arrayOrdered
}
}
对于你的例子做:
let uniqueMessages = messages.unique{[=11=].id ?? ""}
使用基于给定键的相等比较创建数组的免费复制版本
public extension Sequence {
public func uniq<Id: Hashable >(by getIdentifier: (Iterator.Element) -> Id) -> [Iterator.Element] {
var ids = Set<Id>()
return self.reduce([]) { uniqueElements, element in
if ids.insert(getIdentifier(element)).inserted {
return uniqueElements + CollectionOfOne(element)
}
return uniqueElements
}
}
public func uniq<Id: Hashable >(by keyPath: KeyPath<Iterator.Element, Id>) -> [Iterator.Element] {
return self.uniq(by: { [=10=][keyPath: keyPath] })
}
}
public extension Sequence where Iterator.Element: Hashable {
var uniq: [Iterator.Element] {
return self.uniq(by: { (element) -> Iterator.Element in
return element
})
}
}
用法
let numbers = [1,2,3,4,5,6,7,1,1,1,]
let cars = [Car(id:1), Car(id:1), Car(id:2)]
numbers.uniq
cars.uniq(by: { [=11=].id})
cars.uniq(by: \Car.id)
cars.uniq(by: \.id)
这是 Array
对 return 基于 keyPath
的唯一对象列表的扩展:
extension Array {
func uniques<T: Hashable>(by keyPath: KeyPath<Element, T>) -> [Element] {
return reduce([]) { result, element in
let alreadyExists = (result.contains(where: { [=10=][keyPath: keyPath] == element[keyPath: keyPath] }))
return alreadyExists ? result : result + [element]
}
}
}
用法:
myChats.uniques(by: \.id)
我有一个自定义 class 定义如下:
class DisplayMessage : NSObject {
var id : String?
var partner_image : UIImage?
var partner_name : String?
var last_message : String?
var date : NSDate?
}
现在我有一个数组 myChats = [DisplayMessage]?
。 id
字段对于每个 DisplayMessage
对象都是唯一的。我需要检查我的数组并从中删除所有重复项,基本上确保数组中的所有对象都具有唯一的 id
。我已经看到一些使用 NSMutableArray
和 Equatable
的解决方案,但是我不确定如何在这里调整它们;我也知道 Array(Set(myChats))
但这似乎不适用于自定义对象数组。
您可以使用一组字符串来完成,如下所示:
var seen = Set<String>()
var unique = [DisplayMessage]
for message in messagesWithDuplicates {
if !seen.contains(message.id!) {
unique.append(message)
seen.insert(message.id!)
}
}
我们的想法是保留一组到目前为止我们已经看到的所有 ID,循环遍历所有项目,然后添加我们没有看到的 ID。
这是 return 基于给定键的唯一对象列表的数组扩展:
extension Array {
func unique<T:Hashable>(map: ((Element) -> (T))) -> [Element] {
var set = Set<T>() //the unique list kept in a Set for fast retrieval
var arrayOrdered = [Element]() //keeping the unique list of elements but ordered
for value in self {
if !set.contains(map(value)) {
set.insert(map(value))
arrayOrdered.append(value)
}
}
return arrayOrdered
}
}
对于你的例子做:
let uniqueMessages = messages.unique{[=11=].id ?? ""}
使用基于给定键的相等比较创建数组的免费复制版本
public extension Sequence {
public func uniq<Id: Hashable >(by getIdentifier: (Iterator.Element) -> Id) -> [Iterator.Element] {
var ids = Set<Id>()
return self.reduce([]) { uniqueElements, element in
if ids.insert(getIdentifier(element)).inserted {
return uniqueElements + CollectionOfOne(element)
}
return uniqueElements
}
}
public func uniq<Id: Hashable >(by keyPath: KeyPath<Iterator.Element, Id>) -> [Iterator.Element] {
return self.uniq(by: { [=10=][keyPath: keyPath] })
}
}
public extension Sequence where Iterator.Element: Hashable {
var uniq: [Iterator.Element] {
return self.uniq(by: { (element) -> Iterator.Element in
return element
})
}
}
用法
let numbers = [1,2,3,4,5,6,7,1,1,1,]
let cars = [Car(id:1), Car(id:1), Car(id:2)]
numbers.uniq
cars.uniq(by: { [=11=].id})
cars.uniq(by: \Car.id)
cars.uniq(by: \.id)
这是 Array
对 return 基于 keyPath
的唯一对象列表的扩展:
extension Array {
func uniques<T: Hashable>(by keyPath: KeyPath<Element, T>) -> [Element] {
return reduce([]) { result, element in
let alreadyExists = (result.contains(where: { [=10=][keyPath: keyPath] == element[keyPath: keyPath] }))
return alreadyExists ? result : result + [element]
}
}
}
用法:
myChats.uniques(by: \.id)