【问题标题】:How do you flatten a set while keeping the parent object?如何在保留父对象的同时展平集合?
【发布时间】:2013-03-20 01:21:43
【问题描述】:

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

我知道我collect类似于select many,但我不知道如何在维护父(程序集)信息的同时使用它。

【问题讨论】:

标签: f#


【解决方案1】:

您可以使用collect 实现SelectMany,方法是将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 }

【讨论】:

  • 太棒了,很多有用的信息可以从这里学习。再次感谢!
【解决方案2】:

看起来你只需要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>

【讨论】:

  • 说真的,我在这个问题上花了太多时间来回答这么简单的问题。呵呵,非常感谢!
猜你喜欢
  • 2021-06-09
  • 2020-04-27
  • 2011-07-23
  • 1970-01-01
  • 2016-02-02
  • 2017-06-11
  • 1970-01-01
  • 2018-05-25
  • 2016-05-14
相关资源
最近更新 更多