如何在保留父对象的同时展平集合?

时间:2013-03-19 16:38:38

标签: f#

在C#中,你只需使用SelectMany,它有一个重载来保持父对象。你怎么在F#做同样的事情?也就是说,我想迭代一组程序集并返回所有具有实现特定属性的类的程序集。

我知道我collect类似于选择多个,但我不确定如何在维护父(汇编)信息时使用它。

2 个答案:

答案 0 :(得分:1)

您似乎只需要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>

答案 1 :(得分:1)

您可以使用SelectMany通过将collect应用于要为“父级”集合的每个元素返回的“子级”集合来实现map

假设您有一些source,并希望让孩子使用getChildren(对于source中的每个元素),然后您想使用selectResult来计算结果无论是孩子还是父母,您都可以使用SelectMany编写以下内容:

source.SelectMany
  ( (fun parent -> getChildren parent),
    (fun parent child -> selectResult parent child ) )

使用collect,相同的代码如下所示(请注意,map操作应用于我们传递给collect的lambda函数中 - 其中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 }