2016-05-25 8 views
9

私はすべてのUITouchで実行したいクロージャの配列を持っているとしましょう。ネストされたforeach文があります私のことをスウィフト - ネストされたfor each closuresを避ける?

touches.filter { touch in 
    return touch.phase == .Ended && touch.tapCount == 1 
}.forEach { touch in 
    actionsOnTap.forEach { action in 
     action(touch) 
    } 
} 

それのバグ、と私はそのような場合のために正確に適用することができ、いくつかのクリーンな方法はありだと思うが、私はそれを考えることはできません。 は、ここに私が使用するコードです。誰も私にヒントを与えることができますか?

+0

フィルタ部は、次のようになります。 'touches.filter {$ 0.phase == .Ended && $ 0.tapCount == 1}おそらく排除することができる' – Daniel

+0

'filter'をまとめて' forEach'の 'guard'に置き換えてください。これにより、インデントが減少し、効率も向上します。また、あなたは別のインデントレベルに移動しないように 'actionsOnTap.forEach {$ 0(touch)}'を使うこともできます。 – Hamish

+5

各タッチを各アクションと組み合わせるには、何らかのネストループが必要です。私は2つのリストの "製品"を作成するための組み込みのライブラリ関数はないと思うが、間違いかもしれない。あなたはその目的のためにユーティリティー機能を作ることができます。 http://stackoverflow.com/questions/30422312/swift-list-product –

答えて

6

ロジックからfilterを削除し、効率と簡潔さのために、代わりに最初のループの内側にguardを使用する必要があります。私はまた、forEachの代わりに、従来のforループを使用することの提案 - 少なくとも最初のループについては@Rob's@matt'sに同意します。

(多分クリーナー)の代替が直接where句を使用して、だけでなく、おそらく(あなたがより読みやすい見つける方)単一の行にあなたのforEach折りたたみてforループにタッチ条件ロジックを統合しているが。

私はこのようにそれを記述します

for touch in touches where touch.phase == .Ended && touch.tapCount == 1 { 
    actionsOnTap.forEach{$0(touch)} 
} 
+0

ここで' where'の使用を忘れました。ありがとう。 –

+0

これは間違いなく最適な解決策です。私はループ内の "どこで"のステートメントを使用できるのか分かりませんでした。ありがとう! –

1

2種類の異種アレイタイプがあります。 filterが行う余分な反復を避ける別の解決方法は、あなたがチェックしたいと思うタッチを自分自身でフィルタリングすることです。

個人的に
touches.forEach{ 
    guard $0.phase == .Ended && $0.tapCount == 1 else { return } 

    actions.forEach{ action in 
    action($0) 
    } 
} 
6

、私はの入れ子のような。私は次のように書いています:

for touch in touches { 
    if touch.phase == .Ended { 
     if touch.tapCount == 1 { 
      actionsOnTap.forEach {$0(touch)} 
     } 
    } 
} 

私には、それはきれいで(特に)明確です。

4

forEachfor-inの普遍的な(または適切に共通する)代替品でない理由の良い例です。このコードは、単に伝統的なforループを使用して短い(140文字対186文字)と明確になる:

for touch in touches where touch.phase == .Ended && touch.tapCount == 1 {  
    for action in actionsOnTap { 
     action(touch) 
    } 
} 

また、余分な配列がfilterが行う方法をコピー作成されません。これは、filterを使用しない一般的な理由ではありません。 filterは非常に強力なツールですが、この場合はforを使用するとより効率的ながより明確になります。

guardではなく、@ originaluser2の提案whereを使用するように編集されました。それはおそらくより良いスウィフトです。

関連する問題