2016-12-08 7 views
1

요소가 equatable 프로토콜을 준수하는 배열로 제한된 Swift의 Array 유형에 확장을 추가하려고합니다. 나는 다음과 같은 방법으로 함수를 정의하려고 시도하고있다 :동등한 요소가있는 배열의 Swift Extension이 색인을 호출 할 수 없음 (Of of :)

import Foundation 

extension Array where Iterator.Element: Equatable { 

    func deletedIndicies<T: Equatable>(newArray: [T]) -> [Int] { 

     var indicies = [Int]() 

     for element in self { 

       if newArray.index(of: element) == nil { 

        indicies.append(self.index(of: element)!) 
       } 
     } 

     return indicies 
     } 
    } 
} 

기능의 목적은 newArray에 표시되지 않습니다 원래 배열에서 모든 항목의 인덱스를 반환하는 것입니다.

내가 엑스 코드에 나타나는 오류입니다 : '(: 요소의)'나는 요소 equatable하고 필요로하고 단지 배열에 대한 함수를 정의하고 있기 때문에

유형의 인수 목록 '인덱스'를 호출 할 수 없습니다 newArray의 요소가 동등한 지, 인덱스 메서드를 호출 할 수없는 이유가 확실하지 않습니다.

답변

4

귀하의 방법에 새로운 일반 자리 표시 자 T을 정의하는 중입니다.이 유형은 반드시 Element과 동일한 유형 일 필요는 없습니다. 따라서 newArray.index(of: element)이라고 말하면 을 T 유형의 인수로 전달하려고합니다. 변경할 경우

extension Array where Element : Equatable { 

    func deletedIndicies(byKeeping elementsToKeep: [Element]) -> [Int] { 

     // use flatMap(_:) to iterate over a sequence of pairs of elements with indices, 
     // returning the index of the element, if elementsToKeep doesn't contains it, 
     // or nil otherwise, in which case flatMap(_:) will filter it out. 
     return self.enumerated().flatMap { 
      elementsToKeep.contains($1) ? nil : $0 
     } 
    } 
} 

또한 : 사이드 참고로

extension Array where Element : Equatable { 
    func deletedIndicies(byKeeping elementsToKeep: [Element]) -> [Int] { 
     // ... 
    } 
} 

,이 방법으로도 구현 될 수있다 :

용액 따라서 단순히 newArray: 파라미터 [Element]로 입력 할 것이다 Element에서 Hashable에 대한 제약 조건은 O (n * m) 시간보다는 O (n) 시간에도 구현 될 수 있습니다. 이는 잠재적으로 바람직 할 수 있습니다.

extension Array where Element : Hashable { 

    func deletedIndicies(byKeeping elementsToKeep: [Element]) -> [Int] { 

     // create new set of elements to keep. 
     let setOfElementsToKeep = Set(elementsToKeep) 

     return self.enumerated().flatMap { 
      setOfElementsToKeep.contains($1) ? nil : $0 
     } 
    } 
}