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

时间:2017-05-26 23:48:47

标签: ios arrays swift

我有一组我从JSON数据创建的模型对象。我有成千上万的记录包含重复项,我需要删除它们。如果记录具有相同的"名称",并且相同的"地址"属性。

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

我的模型对象如下所示:

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

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

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

任何人都可以看到我做错了吗?

1 个答案:

答案 0 :(得分:6)

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

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

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:用法

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)

提示:

如果ID是唯一的,则应将其用于比较。