2016-10-01 10 views
0

私はCGPointと配列の配列のいくつかの配列を持つ関数を持っています。私はそれぞれの配列からポイントを手動で削除して、それを一つずつ追加しています。これは確かに退屈で非効率的なアプローチです。私はより効率的な方法を削除し、配列にポイントを追加処理するために探しています。私はポイントにそれらが含まれているアレイからp1p3p7を削除し、配列のノートを取り、バックポジションを追加する方法を、例えば複数の配列から要素を削除してもう一度追加するにはどうすればよいですか?

func setSpritePositions() { 
    groupA1 = [p1, p4, p6, p8] 
    groupA2 = [p1, p3, p2, p5] 

    groupB1 = [p1, p7, p2, p6] 
    groupB2 = [p9, p4, p3, p2] 
    groupB2 = [p2, p4, p5, p8] 

    groupC1 = [p1, p7, p2, p7] 
    groupC2 = [p9, p4, p3, p2] 
    groupC3 = [p4, p5, p6, p7] 
    groupC4 = [p5, p1, p3, p4] 

    groupA = [groupA1, groupA2] 
    groupB = [groupB1, groupB2, groupB3] 
    groupC = [groupC1, groupC2, groupC3, groupC4] 

    groups = [groupA, groupB, groupC] 

} 

:ここに私のコードです。どのように私はそれを達成するだろうか?私が言ったように、私はそれを一つずつやってきましたが、それはあまりにも面倒です。

UPDATE

私は私のゲームでのスプライトの移動を制限する位置のさまざまなグループを使用しています。時々、私は特定の位置を削除し、どの配列を後で追加するかを知ることができます。

+0

'groups'を繰り返します。各配列に対して、その配列を繰り返します。これらの配列のそれぞれに対して、ポイントが含まれているかどうかを確認します。その場合は、削除してから追加してください。 – rmaddy

+0

@rmaddyあなたは 'groups'を通して他のすべての配列にアクセスしていますか?私はすべての他の配列を使用していますので、 'group'の変更だけでは、他の配列では影響を受けません。 NSArrayの使用を検討していましたが、特定の結果を得るために操作するのは非常に難しいでしょう。 – OnlyCodeMatters

+0

"の位置を追加し、"実際には配列の末尾に置くかどうかここに追加することを意味しますか? "という意味ですか?p1がアクティブな場合があります。"私は後者を前提としていて、あるグループでp1が非アクティブであれば、すべてのグループで非アクティブです。 –

答えて

1

答えはより良いタイプです。まず、ポイントを共有状態にしたい場合は、値タイプではなく参照タイプが必要です。ポイントを参照に移動する必要があります。

final class Location { 
    let point: CGPoint 
    var isActive: Bool = true 
    init(_ point: CGPoint) { self.point = point } 
} 

ここでは、場所のオンとオフを切り替えることができます。

ここでは、より良いタイプのものを使用する方法の例を示します。これを設計する方法はたくさんあります。これはただのものです。次に、場所をセグメントにグループ化できます。

struct LocationSegment { 
    let locations: [Location] 
    var activePoints: [CGPoint] { 
     return locations.filter{ $0.isActive }.map{ $0.point }.uniqueValues() 
    } 
} 

これで、アクティブなポイントのリストを簡単に取得できます。これは、のような拡張を前提としています

extension Array where Element: Equatable { 
    // Warning: This is O(n^2). You can't do better than that without making CGPoint Hashable 
    // (which is easy, but left as a separate problem.) 
    func uniqueValues() -> [Element] { 
     var result: [Element] = [] 
     for element in self { 
      if !result.contains(element) { 
       result.append(element) 
      } 
     } 
     return result 
    } 
} 

を今、私たちは、セグメントを持っていることを、私たちはグループでそれらを置くことができます:

struct LocationGroup { 
    let segments: [LocationSegment] 
    var activePoints: [CGPoint] { return segments.flatMap { $0.activePoints }.uniqueValues() } 
} 

そして、我々はグループの配列を持っていた場合:

let groups = [groupA, groupB, groupC] 

私たちは、すべてのアクティブポイントを得ることができます:

groups.flatMap { $0.activePoints } 

これもやはり1つの方法です。 groups[LocationGroup]よりも強力な型にするか、LocationGroupを再帰的列挙型に再設計して、これを値型で完全に構築できるようにすることができます(この特定の問題は下部の参照型について叫ぶと思います) 。重要な点は、配列を強制的にすべてのものにするのではなく、何を意味するのかを示す型を構築することです。

+0

うわー!これはこの問題を解決するだけではありませんでしたが、私が持っていた半ダースの問題を解決しました。ありがとう、本当に感謝します。 – OnlyCodeMatters

関連する問題