Swift - 如何检查数组中是否存在具有某些属性的元素?

时间:2016-11-21 23:21:46

标签: ios arrays swift

在我的NookController中,我有以下内容:

    var nooks = [NookController(name:"Library",coordinate:CLLocationCoordinate2D(),availability:.Empty, hours: "Open 24 hours"),
            NookController(name:"Math Building",coordinate:CLLocationCoordinate2D(),availability:.Empty, hours: "Open 24 hours")]

在我的ViewController中,我创建了以下函数来验证我附加的新“Nook”是否重复:

func checkDuplicates() -> Bool {
        if nooks.contains(NookController(name:"Library",coordinate:CLLocationCoordinate2D(),availability:.Empty,hours:"Open 24 hours")) {
            return true
        }
        else {
            return false
    }
}

但是,我正在测试这个并且当我实际上在该数组中已经存在的数组中添加一个元素时它无效(它总是返回false)。

2 个答案:

答案 0 :(得分:0)

覆盖NookController类的equals运算符:

ghci> :m +Data.Singletons.Prelude
ghci> :set -XDataKinds
ghci> fromSing (sing :: Sing 'True)
True

然后使用它:

func == (left: NookController, right: NookController) -> Bool {
    return left.name == right.name
}

答案 1 :(得分:0)

你需要为Nook定义“相同”的含义 - 它是否是相同的坐标?同名?都?同样的时间也是?

完成此操作后,您需要使NookController符合Equatable协议并实施==功能。例如:

extension NookController: Equatable {
     static func ==(lhs: NookController, rhs: NookController) -> Bool {

        if lhs.name == rhs.name &&
            lhs.location.latitude == rhs.location.latitude &&
            lhs.location.longitude == rhs.location.longitude {
            return true
        } else {
            return false
        }
    }
}

var nooks = [NookController(name: "Library", location: CLLocationCoordinate2D(), availability: .Empty, hours: "24 hours"),
         NookController(name: "Math Building", location: CLLocationCoordinate2D(), availability: .Empty, hours: "24 hours")
]

let testNook = NookController(name: "Library", location: CLLocationCoordinate2D(), availability: .Empty, hours: "24 hours")

print(nooks.contains(testNook))  // Prints true

虽然正如@Ryan建议的那样,你应该为每个角落都有一个唯一ID(如果要将数据保存在某种数据存储中,你肯定会想要这个)并使用它来测试相等性。

您的课程也应符合Hashable。这将允许它在集合中使用(用于消除重复)并用作字典键:

extension NookController: Hashable {
    var hashValue: Int {
        return self.name.hash ^ Int(self.location.latitude) ^ Int(self.location.longitude)
    }
}