2016-07-13 5 views

答えて

8

あなたは、配列の要素が0であることを必要としている約item

ここでエラーが私のコードですself.contains(item)行で

Cannot convert value of type 'T.Generator.Element' to expected argument type '@noescape _ throws -> Bool' 
, ですが、配列要素とは無関係です。したがって、

if !self.contains(item) { ... } 

はコンパイルされません。

extension Array where Element: Equatable { 
    func containsArray<T : SequenceType where T.Generator.Element == Element> (array:T) -> Bool { 
     for item in array { 
      if !self.contains(item) { 
       return false 
      } 
     } 
     return true 
    } 
} 

をあなただけではなく配列引数のための方法が必要な場合:

あなたはおそらくしたいことは、配列の要素は配列要素として 同じ型を持っている(そしてそれはEquatableでなければならない)ことを要求することです 一般的なシーケンスのためにあなたが

に短縮することができ

extension Array where Element: Equatable { 
    func containsArray(array: [Element]) -> Bool { 
     for item in array { 
      if !self.contains(item) { 
       return false 
      } 
     } 
     return true 
    } 
} 

に宣言を簡素化することができます

extension Array where Element: Equatable { 
    func containsArray(array: [Element]) -> Bool { 
     return !array.contains { !self.contains($0) } 
    } 
} 

@AMomchilovが言ったように、は、線形探索を行うので、この はMNが 2つの配列の長さO(M*N)複雑性を有します。あなたは、要素がHashableされる場合 のための特殊化を定義し、Setに対するメンバーシップのチェック を行うことができます:

extension Array where Element: Hashable { 
    func containsArray(array: [Element]) -> Bool { 
     let selfSet = Set(self) 
     return !array.contains { !selfSet.contains($0) } 
    } 
} 

これは、以前の方法よりも高速かどうかを、両方 配列のサイズに依存するであろうし、 (要素を比較するには "高価"なので )。

+0

OPへの注記:これは、セットが使用されている場合は、スピードを上げることができます。 '.contains'は遅い線形検索を行います。この解法は全体的に二次的な時間の複雑さを有する。 – Alexander

+1

@AMomchilov:はい(要素が 'Hashable'の場合)。 –

+0

@AMomchilovだから何をお勧めしますか? – iOSGeek

関連する問題