查找多个数组的元素是否具有相同的坐标

Find whether several array's elements have the same coordinates

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

这是扩展...

import Foundation

extension Array where Element : Equatable {

    func equalCoordinates() -> Bool {

        if let firstElement = first {

            return dropFirst().contains { [=10=] == firstElement }

        }

        return true
    }
}

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

...以及 ViewController 中使用 equalCoordinates() 方法的代码:

func drawn() {

    let colorArray = array.map { [=11=].pointCoord()[0] }

    for dot in array {

        for cPoint in dot.pointCoord() {

            if colorArray.equalCoordinates() {

                let altColor = dot.alternativePointColour()
                draw(cPoint, color: altColor)

            } else {

                let color = dot.pointColour()
                draw(cPoint, color: color)
            }
        }
    }
}

...........

Swift.print(colorArray.equalCoordinates())

...........

完全不考虑效率(可以根据数据的大小进行改进),这就是我可能会采用的方式。每件作品都非常简单,因此您应该能够使其适应各种不同的输出(例如,如果您喜欢 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 { [=10=].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]]

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 { [=10=].indexSet }
    }
}