2017-03-15 7 views
0

学習の練習として、私はUnderscore.jsのユーティリティ関数の一部を素早く移植していますが、コレクション内の要素が指定されたコレクションブロックを通過するとtrueを返すsomeから始まります。Underscoreのいくつかの機能を迅速に移植する

ナイーブな実装:

extension Sequence { 
    func some(_ predicate: (Self.Iterator.Element) -> Bool) -> Bool { 
     return reduce(false) { $0 || predicate($1) } 
    } 
} 

に私は、しかし、STLの機能の多くはthrowsrethrowsが含まれていることに気づきました。偉大な例では、関数のシグネチャを持つfilter機能である:

func filter(_ isIncluded: (Element) throws -> Bool) rethrows -> [Element] 

誰かがまたthrowrethrows機能を活用しながら、some機能を作成する方法を見せてもらえますか?

答えて

0

このブログの記事は良い概要です:http://robnapier.net/re-throws

基本的には、rethrowsは、その閉鎖パラメータの一つをスローした場合に機能のみをスローすることの指標です。これは、スローしないクロージャで関数を呼び出すと投げを処理する必要がないように強制します。さて、someは投げまたは非投げ述語を受け入れます、そしてあなたはそれを非投げ述語を与えた場合、あなたがする必要はありません

extension Sequence { 
    func some(_ predicate: (Self.Iterator.Element) throws -> Bool) rethrows -> Bool { 
     return reduce(false) { $0 || try predicate($1) } 
    } 
} 

:あなたのケースでは、あなただけのようにあなたの拡張メソッドを定義しますtryについて心配。

+0

私はすでにそれを試しましたが、 "コールはスローすることができますが、試しにマークされていません"というコンパイルに失敗します。私は実際に 'map'と' reduce'を組み合わせて使ってどのように達成するかを考えました。共有する答えを投稿します。 – barndog

+0

私は述語の呼び出しの前に '試行 'を入れるのを忘れていました。私はコードを更新します。 –

0

mapreduceの組み合わせを使用して私の質問を解決することができました。私は、迅速な遊び場を作った:

extension Sequence { 
    func some(_ predicate: (Self.Iterator.Element) throws -> Bool) rethrows -> Bool { 
     return try map(predicate).reduce(false) { $0 || $1 } 
    } 
} 

let list = [1, 2, 3] 
list.some({ $0 == 1 }) // true 
list.some({ $0 % 50 == 0 }) // false 

マップを使用して、あなたはboolsの配列に配列全体をマッピングし、各要素に述語を適用し、その後、それらを一緒に論理和(OR)。

これは最も効率的なアルゴリズムではなく、trueなどの値が出てすぐに戻ってしまうなどの明確な最適化がありますが、私はソリューションの単純な機能が好きです。

関連する問題