找出几个数组的元素是否具有相同的坐标

时间:2016-09-25 12:42:48

标签: arrays macos swift2 equality

我正在写一个Swift mvn clean compile来检查数组中的两个或多个CGPoints是否具有相同的坐标。有了这段代码,我可以检查数组中的所有点。 但是如何检查几个元素(不是全部)?

这是扩展程序......

mvn clean compile

如果两个(或更多)红色CGPoints具有相同的坐标,则必须将它们变为绿色。

...使用extension方法在ViewController中使用代码:

import Foundation

extension Array where Element : Equatable {

    func equalCoordinates() -> Bool {

        if let firstElement = first {

            return dropFirst().contains { $0 == firstElement }

        }

        return true
    }
}

2 个答案:

答案 0 :(得分:2)

绝对不关心效率(可以根据数据的大小改进),这就是我可能会去做的事情。每个部分都非常简单,因此您应该能够将其调整为各种不同的输出(例如,如果您更喜欢IndexSet之外的其他内容)。

import Foundation
import CoreGraphics

// We could put this on Collection rather than Array, but then we'd have to rewrite
// IndexSet on generic indices or use [Index].
extension Array where Element : Equatable {

    func uniqueElements() -> [Element] {
        // This is O(n^2), but it's hard to beat that without adding either 
        // Hashable (for Set) or Comparable (to pre-sort) to the requirements,
        // neither of which CGPoints have by default.
        var uniqueElements: [Element] = []

        for element in self {
            if !uniqueElements.contains(element) {
                uniqueElements.append(element)
            }
        }
        return uniqueElements
    }

    func indexSet(of element: Element) -> IndexSet {
        var indices = IndexSet()
        for (index, member) in enumerated() {
            if element == member {
                indices.insert(index)
            }
        }
        return indices
    }

    func indexSetsGroupedByEquality() -> [(element: Element, indexSet: IndexSet)] {
        return uniqueElements().map { element in (element, indexSet(of: element)) }
    }

    func indexSetsOfCollidingElements() -> [IndexSet] {
        func hasCollisions(_: Element, indexSet: IndexSet) -> Bool { return indexSet.count > 1 }

        return indexSetsGroupedByEquality()
            .filter(hasCollisions)
            .map { $0.indexSet }
    }
}

let points  = [
    CGPoint(x:1,y:1),
    CGPoint(x:2,y:1),
    CGPoint(x:1,y:1),
    CGPoint(x:3,y:1),
    CGPoint(x:2,y:1),
]

print(points.indexSetsOfCollidingElements().map(Array.init))

// [[0, 2], [1, 4]]

答案 1 :(得分:0)

Swift 2.2版本

extension Array where Element : Equatable {


    func uniqueElements() -> [Element] {

        var uniqueElements: [Element] = []

        for element in self {

            if !uniqueElements.contains(element) {

                uniqueElements.append(element)
            }
        }
        return uniqueElements
    }



    func indexSet(of element: Element) -> NSIndexSet {

        let indices = NSIndexSet()

        for (index, member) in enumerate() {

            if element == member {

                indices.insertValue(index, inPropertyWithKey: "")
            }
        }
        return indices
    }



    func indexSetsGroupedByEquality() -> [(element: Element, indexSet: NSIndexSet)] {

        return uniqueElements().map { element in (element, indexSet(of: element)) }
    }



    func indexSetsOfCollidingElements() -> [NSIndexSet] {

        func hasCollisions(_: Element, indexSet: NSIndexSet) -> Bool {

            return indexSet.count > 0
        }

        return indexSetsGroupedByEquality()

        .filter(hasCollisions)

        .map { $0.indexSet }
    }
}