2016-10-01 3 views
0

나는 배열이 배열 인 CGPoint의 여러 배열을 가지고있다. 각 배열에서 '수동으로'점을 제거하고 하나씩 다시 추가했습니다. 확실히 지루하고 비효율적 인 접근 방법입니다. 배열을 제거하고 점을 추가하는 효율적인 방법을 찾고 있습니다. 나는 점을 포함하는 배열에서 p1, p3p7을 제거하고 배열의 주를 가지고 다시 위치를 추가 할 방법, 예를 들어여러 배열에서 요소를 제거하고 다시 추가하는 방법은 무엇입니까?

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'를 통해 다른 모든 배열에 접근하는 것을 말하고 있습니까? 나는 다른 모든 배열을 사용하고 있기 때문에 신속한 배열은 값 유형이므로'groups'의 변경만으로는 다른 그룹에서 변경되지 않습니다. 나는 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 } 

다시 한번 말하지만 이것은 하나의 접근법 일뿐입니다. groups[LocationGroup]보다 강력한 형식으로 만들거나 LocationGroup을 재귀 열거 형으로 재 설계하여 값 유형으로 전체를 빌드 할 수 있도록 할 수 있습니다 (이 특정 문제는 참조 유형이 아래쪽에 울려 퍼지기는하지만). . 요점은 배열을 원하는 모든 것으로 강제하기보다는 의미가 무엇인지 말하는 유형을 만드는 것입니다.

+0

와우!이 문제를 해결할뿐만 아니라 내가 가진 여섯 가지 다른 문제를 해결했습니다. 정말 감사드립니다. – OnlyCodeMatters

관련 문제