2016-09-25 7 views
1

配列の中の2つ以上のCGPointが同じ座標を持つかどうかを調べるSwift extensionを書いています。このコードを持つことで、配列内のすべての点をチェックできます。 しかし、いくつかの要素(すべてではない)だけをチェックする方法は? 2つ(またはそれ以上)の赤CGPointsは、彼らが緑色のものに変えなければなりません同じ座標を持っている場合は複数の配列の要素が同じ座標を持っているかどうかを調べる

はここ

import Foundation 

extension Array where Element : Equatable { 

    func equalCoordinates() -> Bool { 

     if let firstElement = first { 

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

     } 

     return true 
    } 
} 

...拡張子です。

...とequalCoordinates()方法使用のViewControllerのコード:(それはあなたのデータのサイズに応じて改善することができる)、効率に与える全く心配して

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範囲内の2つ以上のCGPoint。可能であれば指標付き。 – 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

そのマップは単にインデックスセットから配列に到達するので、より簡単に印刷できます。あなたはそれを必要としません。インデックスセットではなくインデックスの配列が必要な場合は、最初に配列を生成するコードを書き直すだけです。あなたが書き直す方法が不明な場合、これはIMOが勉強する良いコードです。あなたはそれが何をしているのかを正確に理解できるはずです。ここには難しいものはありません。 (まだ問題がある場合は、問題のあるメソッドについて質問して、答えにコメントを追加します) –

+0

Xcodeは 'Type '[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 } 
    } 
} 
関連する問題