2016-09-25 59 views
1

我在寫一個Swift extension,它檢查數組中的兩個或多個CGPoint是否具有相同的座標。有了這個代碼,我可以檢查數組中的所有點。 但如何檢查幾個元素(不是全部)?查找幾個數組的元素是否具有相同的座標

這裏的延伸......

import Foundation 

extension Array where Element : Equatable { 

    func equalCoordinates() -> Bool { 

     if let firstElement = first { 

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

     } 

     return true 
    } 
} 

如果兩個(或更多)紅色CGPoints具有相同的座標,必須將它們變成綠色的。

...在使用的ViewController方法equalCoordinates()代碼:

func drawn() { 

    let colorArray = array.map { $0.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()) 

........... 
+0

你說的幾個意思?他們的範圍?他們的一組索引?一次一個? – ColGraff

+0

@ColGraff一個範圍內的兩個或多個CGPoints。如果可能的話,用索引。 – andy

+0

所以你還想要返回相等元素的索引? – ColGraff

回答

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]] 
+0

非常感謝,羅布。但我有一個錯誤。我輸入'colorArray.indexSetsOfCollidingElements().map(Array.init)',並在Xcode中得到一條消息:'對成員init''不明確的引用。有沒有解決方法? – andy

+1

該映射只是從IndexSet進入數組,因此我可以更輕鬆地打印它。你通常不需要這個。如果你想要一個索引數組而不是索引集,只需重寫代碼來首先生成數組。如果你不清楚如何改寫它,這是IMO一個很好的學習代碼。你應該能夠弄清楚它正在做什麼。這裏沒有任何意圖是棘手的。 (如果仍有問題,請詢問您遇到的問題,並在答案中添加更多註釋。) –

+0

Xcode說:'類型'[NSIndexSet]'不符合協議'BooleanType'' 。 – andy

0

雨燕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 } 
    } 
} 
相關問題