查找多个数组的元素是否具有相同的坐标
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 }
}
}
我正在编写一个 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 }
}
}