C#SelectMany
では、親オブジェクトを保持するためのオーバーロードがあるを使用します。F#で同じことをどのように行いますか?つまり、一連のアセンブリを繰り返し処理し、特定の属性を実装するクラスを持つすべてのアセンブリを返します。
多くを選択するのと似ていることは知ってcollect
いますが、親(アセンブリ)情報を維持しながら使用する方法がわかりません。
C#SelectMany
では、親オブジェクトを保持するためのオーバーロードがあるを使用します。F#で同じことをどのように行いますか?つまり、一連のアセンブリを繰り返し処理し、特定の属性を実装するクラスを持つすべてのアセンブリを返します。
多くを選択するのと似ていることは知ってcollect
いますが、親(アセンブリ)情報を維持しながら使用する方法がわかりません。
filter
代わりに必要なようですcollect
:
let hasTypeWithAttribute<'t when 't :> Attribute> (a: Assembly) = a.GetTypes() |> Array.exists (fun t -> t.GetCustomAttributes(typeof<'t>, true).Length > 0)
let assemblies = inputSet |> Set.filter hasTypeWithAttribute<AttributeName>
「親」コレクションの各要素に対して返したい「子」のコレクションにを適用することにより、をSelectMany
使用して実装できます。collect
map
いくつかあり、 (の各要素に対して)source
を使用して子を取得したい場合、子と親の両方を使用して結果を計算する場合は、次を使用して次のように記述できます。getChildren
source
selectResult
SelectMany
source.SelectMany
( (fun parent -> getChildren parent),
(fun parent child -> selectResult parent child ) )
を使用するcollect
と、同じコードは次のようになります(map
操作は渡されるラムダ関数内で適用されることに注意してくださいcollect
-parent
まだスコープ内にあります):
source |> Seq.collect (fun parent ->
getChildren parent
|> Seq.map (fun child ->
selectResult parent child ))
SelectMany
によってキャプチャされた動作は、次のようなF#シーケンス式を使用して、おそらくより読みやすい方法で実装できることにも注意してください。
seq { for parent in source do
for child in getChildren parent do
yield selectResult parent child }