从Swift自定义对象数组中删除重复项

时间:2021-02-07 07:38:23

I have a custom class defined as follows :

我有一个自定义类定义如下:

class DisplayMessage : NSObject {
var id : String?
var partner_image : UIImage?
var partner_name : String?
var last_message : String?
var date : NSDate?
}

Now I have an array myChats = [DisplayMessage]?. The id field is unique for each DisplayMessage object. I need to check my array and remove all duplicates from it, essentially ensure that all objects in the array have a unique id. I have seen some solutions using NSMutableArray and Equatable however I'm not sure how to adapt them here; I also know of Array(Set(myChats)) however that doesn't seem to work for an array of custom objects.

现在我有一个数组myChats = [DisplayMessage]? id字段对于每个DisplayMessage对象都是唯一的。我需要检查我的数组并从中删除所有重复项,基本上确保数组中的所有对象都具有唯一的ID。我已经看到了一些使用NSMutableArray和Equatable的解决方案但是我不确定如何在这里调整它们;我也知道Array(Set(myChats))然而,这似乎不适用于自定义对象数组。

2 个解决方案

#1


7  

You can do it with a set of strings, like this:

您可以使用一组字符串来完成,如下所示:

var seen = Set<String>()
var unique = [DisplayMessage]
for message in messagesWithDuplicates {
    if !seen.contains(message.id!) {
        unique.append(message)
        seen.insert(message.id!)
    }
}

The idea is to keep a set of all IDs that we've seen so far, go through all items in a loop, and add ones the IDs of which we have not seen.

我们的想法是保留一组我们到目前为止看到的所有ID,遍历循环中的所有项目,并添加我们尚未看到的ID。

#2


9  

Here is an Array extension to return the unique list of objects based on a given key:

这是一个Array扩展,用于根据给定的键返回唯一的对象列表:

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

for your example do:

为你的例子做:

let uniqueMessages = messages.unique{$0.id ?? ""}

#1


7  

You can do it with a set of strings, like this:

您可以使用一组字符串来完成,如下所示:

var seen = Set<String>()
var unique = [DisplayMessage]
for message in messagesWithDuplicates {
    if !seen.contains(message.id!) {
        unique.append(message)
        seen.insert(message.id!)
    }
}

The idea is to keep a set of all IDs that we've seen so far, go through all items in a loop, and add ones the IDs of which we have not seen.

我们的想法是保留一组我们到目前为止看到的所有ID,遍历循环中的所有项目,并添加我们尚未看到的ID。

#2


9  

Here is an Array extension to return the unique list of objects based on a given key:

这是一个Array扩展,用于根据给定的键返回唯一的对象列表:

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

for your example do:

为你的例子做:

let uniqueMessages = messages.unique{$0.id ?? ""}