希望使用过滤器方法基于使用Swift的数组中的两个属性来删除重复的模型对象

时间:2022-09-25 07:58:31

I have an array of model objects that I have created from JSON data. I have thousands of records that contain duplicates, which I need to remove. A record is considered a duplicate if it has the same "name", and the same "address" attributes.

我有一个模型对象数组,我从JSON数据创建。我有成千上万的记录包含重复项,我需要删除它们。如果记录具有相同的“名称”和相同的“地址”属性,则该记录被视为重复记录。

The problem is, the only way I know how to remove the duplicate objects is by performing a for loop, within a for loop search, and I'm wondering if there is not a better, more efficient way? I figure that the best approach for this would be to use the "filter" method, but I'm having difficulty configuring it to work with an array that contains model objects with multiple attributes.

问题是,我知道如何删除重复对象的唯一方法是在for循环搜索中执行for循环,我想知道是否有更好,更有效的方法?我认为最好的方法是使用“过滤器”方法,但我很难配置它来处理包含具有多个属性的模型对象的数组。

My model object looks like this:

我的模型对象如下所示:

struct Person {

    let id: Int
    let name: String
    let address: String


    init(id:Int, name:String, address:String) {
        self.id = id
        self.name = name
        self.address = address
    }
}

The way I'm trying to use the filter method on my array of model objects looks like this (which I know does not work):

我试图在我的模型对象数组上使用filter方法的方式看起来像这样(我知道它不起作用):

let uniqueArray = peopleArray.filter { $0.name == $1.name, $0.address == $1.address }

Can anyone see what it is I'm doing wrong?

任何人都可以看到它是什么我做错了吗?

1 个解决方案

#1


6  

1: You need to make your struct conform to Equatable protocol

1:您需要使您的结构符合Equatable协议

func ==(lhs: Person, rhs: Person) -> Bool {
    return lhs.name == rhs.name && lhs.address == rhs.address
}

2: You can use a set to control which objects to filter from your array but you will need to make your struct conform to Hashable protocol adding a hashValue property to it.

2:您可以使用一个集来控制从阵列中过滤哪些对象,但是您需要使您的struct符合Hashable协议,为其添加hashValue属性。

struct Person: Equatable, Hashable {
    let id: Int
    let name: String
    let address: String
    init(id: Int, name: String, address: String) {
        self.id = id
        self.name = name
        self.address = address
    }
    var hashValue: Int {
        return name.hashValue ^ address.hashValue
    }
}

3: Usage

let people = [Person(id: 1, name: "Name A", address: "Address A"),
              Person(id: 2, name: "Name B", address: "Address B"),
              Person(id: 2, name: "Name B", address: "Address B"),
              Person(id: 3, name: "Name C", address: "Address C")]

// Will keep the order
var set: Set<Person> = []
let orderedset = people.filter{ set.insert($0).inserted }
print(orderedset)

// Will not keep the order
let unique = Set<Person>(people)
print(unique)

Tip:

If the ID is unique you should use it for comparison instead.

如果ID是唯一的,您应该使用它进行比较。

#1


6  

1: You need to make your struct conform to Equatable protocol

1:您需要使您的结构符合Equatable协议

func ==(lhs: Person, rhs: Person) -> Bool {
    return lhs.name == rhs.name && lhs.address == rhs.address
}

2: You can use a set to control which objects to filter from your array but you will need to make your struct conform to Hashable protocol adding a hashValue property to it.

2:您可以使用一个集来控制从阵列中过滤哪些对象,但是您需要使您的struct符合Hashable协议,为其添加hashValue属性。

struct Person: Equatable, Hashable {
    let id: Int
    let name: String
    let address: String
    init(id: Int, name: String, address: String) {
        self.id = id
        self.name = name
        self.address = address
    }
    var hashValue: Int {
        return name.hashValue ^ address.hashValue
    }
}

3: Usage

let people = [Person(id: 1, name: "Name A", address: "Address A"),
              Person(id: 2, name: "Name B", address: "Address B"),
              Person(id: 2, name: "Name B", address: "Address B"),
              Person(id: 3, name: "Name C", address: "Address C")]

// Will keep the order
var set: Set<Person> = []
let orderedset = people.filter{ set.insert($0).inserted }
print(orderedset)

// Will not keep the order
let unique = Set<Person>(people)
print(unique)

Tip:

If the ID is unique you should use it for comparison instead.

如果ID是唯一的,您应该使用它进行比较。