我有一些具有某些属性的对象。
例如:餐馆{名称,纬度,经度,地址}
我想基于特定属性比较每个对象,并返回不同对象的列表。
例如:
Array = [R1, R2, R3, R4, R5]
假设餐馆R4和R5彼此更接近,它们具有相同的纬度和经度。
我需要比较和过滤数组
($0.latitude == $1.latitude and $0.longitude == $1.longitude)
四舍五入到小数点后3位
这样最终结果将包含以下项目[R1, R2, R3, R4]
答案 0 :(得分:1)
class B {
var a: String?
var b: Int?
}
var arr:[B] = []
arr.filter{ index in
var repeatedCount = 0
arr.forEach{
repeatedCount += $0.a == index.a ? 1 : 0
}
return repeatedCount == 1
}
上述解决方案可行,但复杂度为o(arr.count ^ 2),这对大型项目集不利。
您可以概括算法并使其高效。或者在数组distinct
在您的情况下,代码将是这样的:
arr.filter{ index in
var repeatedCount = 0
arr.forEach{
if $0.latitude == index.latitude && $0.longitude == index.longitude {
repeatedCount += 1
}
}
return repeatedCount == 1
}
答案 1 :(得分:1)
正如@kandelvijaya所说,如果你想/必须成对地比较元素,我不确定你能比二次时间做得更好(在许多情况下这很好)。
这是一个通用的O(n)替代方案。两件事:
key
。
extension Sequence {
typealias Element = Iterator.Element
func uniqued<Key: Hashable>(by key: (Element) -> (Key)) -> [Element] {
var seen = Set<Key>()
return filter {
seen.update(with: key($0)) == nil
}
}
}
用法:
let numbers = [1, 1, 1, 2, 2, 3, 1, 2, 3]
let uniqueByValue = numbers.uniqued { $0 }
let strings = ["a", "b", "aa", "bb", "ccc", "dddd"]
let uniqueByLength = strings.uniqued { $0.characters.count }
在你的情况下,这可能是:
let restaurantes = [R1, R2, R3, R4, R5]
let uniques = restaurants.uniqued {
let roundedLat = ...
let roundedLong = ...
return "\(roundedLat), \(roundedLong)"
}