比较并返回基于属性的不同swift数组对象

时间:2016-09-12 09:01:19

标签: ios arrays swift

我有一些具有某些属性的对象。

例如:餐馆{名称,纬度,经度,地址}

我想基于特定属性比较每个对象,并返回不同对象的列表。

例如:

Array = [R1, R2, R3, R4, R5]

假设餐馆R4和R5彼此更接近,它们具有相同的纬度和经度。

我需要比较和过滤数组

($0.latitude == $1.latitude and $0.longitude == $1.longitude)四舍五入到小数点后3位

这样最终结果将包含以下项目[R1, R2, R3, R4]

2 个答案:

答案 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)"
}