枚举本质上不是 IEnumerable 的集合?

2024-05-01

当您想要递归枚举一个分层对象,根据某些条件选择一些元素时,有许多技术示例,例如“扁平化”,然后使用 Linq 进行过滤:就像在这里找到的那​​些:

链接文本 https://stackoverflow.com/questions/141467/recursive-list-flattening

但是,当您枚举 Form 的 Controls 集合或 TreeView 的 Nodes 集合之类的内容时,我无法使用这些类型的技术,因为它们似乎需要一个 IEnumerable 参数(扩展方法)集合:传入 SomeForm.Controls 无法编译。

我发现的最有用的东西是:

链接文本 http://blogs.windowsclient.net/rendle/archive/2008/03/06/recursing-controlcollection.aspx

它确实为您提供了 Control.ControlCollection 的扩展方法,其中包含 IEnumerable 结果,然后您可以将其与 Linq 一起使用。

我已经修改了上面的示例来毫无问题地解析 TreeView 的节点。

public static IEnumerable<TreeNode> GetNodesRecursively(this TreeNodeCollection nodeCollection)
{
    foreach (TreeNode theNode in nodeCollection)
    {
        yield return theNode;

        if (theNode.Nodes.Count > 0)
        {
            foreach (TreeNode subNode in theNode.Nodes.GetNodesRecursively())
            {
                yield return subNode;
            }
        }
    }
}

这是我现在使用扩展方法编写的代码:

    var theNodes = treeView1.Nodes.GetNodesRecursively();

    var filteredNodes = 
    (
        from n in theNodes
            where n.Text.Contains("1")
                select n
    ).ToList();

我认为可能有一种更优雅的方法来执行此操作,其中传入约束。

我想知道是否可以通用地定义此类过程,以便:在运行时我可以将集合的类型以及实际的集合传递给通用参数,因此代码独立于是否它是 TreeNodeCollection 或 Controls.Collection。

我还想知道是否有比第二个链接(上面)中显示的方法更便宜?更快?)以 Linq 可用的形式获取 TreeNodeCollection 或 Control.ControlCollection 。

Leppie 在链接到第一个(上面)的 SO 帖子中关于“SelectMany”的评论似乎是一个线索。

我对 SelectMany 的实验是:好吧,称它们为“灾难”。 :)

感谢任何指点。我花了几个小时阅读了我能找到的所有涉及这些领域的 SO 帖子,并漫无目的地进入了“y-combinator”这样的奇特事物。我可能会补充说,这是一次“谦卑”的经历:)


这段代码应该可以解决问题

public static class Extensions
{
    public static IEnumerable<T> GetRecursively<T>(this IEnumerable collection,
        Func<T, IEnumerable> selector)
    {
        foreach (var item in collection.OfType<T>())
        {
            yield return item;

            IEnumerable<T> children = selector(item).GetRecursively(selector);
            foreach (var child in children)
            {
                yield return child;
            }
        }
    }
}

这是如何使用它的示例

TreeView view = new TreeView();

// ...

IEnumerable<TreeNode> nodes = view.Nodes.
    .GetRecursively<TreeNode>(item => item.Nodes);

Update:回应埃里克·利珀特的帖子。

这是使用中讨论的技术的一个大大改进的版本关于迭代器的一切 http://blogs.msdn.com/wesdyer/archive/2007/03/23/all-about-iterators.aspx.

public static class Extensions
{
    public static IEnumerable<T> GetItems<T>(this IEnumerable collection,
        Func<T, IEnumerable> selector)
    {
        Stack<IEnumerable<T>> stack = new Stack<IEnumerable<T>>();
        stack.Push(collection.OfType<T>());

        while (stack.Count > 0)
        {
            IEnumerable<T> items = stack.Pop();
            foreach (var item in items)
            {
                yield return item;

                IEnumerable<T> children = selector(item).OfType<T>();
                stack.Push(children);
            }
        }
    }
}

我使用以下内容做了一个简单的性能测试基准测试技术 https://stackoverflow.com/questions/1507405/c-is-this-benchmarking-class-accurate。结果不言自明。树的深度对第二种解决方案的性能只有边际影响;而第一个解决方案的性能迅速下降,最终导致StackOverflowException当树的深度变得太大时。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

枚举本质上不是 IEnumerable 的集合? 的相关文章

随机推荐

  • 如何在动画结束时开始活动

    这是我的第一个应用程序 我需要在动画结束时开始新的活动 我需要做什么 我的代码 package com lineage goddess import android app Activity import android content I
  • Nhibernate:2 列总和的限制

    我可以使用 HNibernate Criteria 创建此 sql 查询吗 从表 1 中选择 其中列 1 gt 列 2 列 3 所有 3 列都是 int32 谢谢 好吧 在第 n 次阅读了这个问题的问题后 我决定编写一个不包括编写 SQL
  • Python OpenCV:检测大体运动方向?

    我仍在编写一个书籍扫描脚本 现在 我所需要的只是能够自动检测翻页 这本书占据了 90 的屏幕 我使用一个粗糙的网络摄像头进行运动检测 所以当我翻页时 运动方向基本上是同一个方向 我修改了一个运动跟踪脚本 但导数却无济于事 usr bin e
  • %d 为长整型

    下面的代码正确吗 据我的理解 它应该不能正常工作 但是在Dev C 编译器上 它可以正常工作 有人可以详细解释一下吗 include
  • Axios 使用 JSONPlaceholder 返回乱码

    我正在尝试学习使用 Axios 获取 API 数据 最终与 HubSpot API 一起使用 我已经建立了一个小型测试项目 尝试使用 fetch 和 Axios 从 JSONPlaceholder 和 RapidAPI FamousQuot
  • Capybara+Selenium:如何在集成测试代码中初始化数据库并使其在 Rails 应用程序中可见?

    配置 使用 RSpec Capybara Selemium 驱动程序 SQLite 数据库对 Rails 项目进行集成测试 情况 我与 Capybara 和默认的rack test 驱动程序进行了一些集成测试 他们直接在数据库中创建用户注册
  • UUID 作为 MySQL id 列的默认值

    我正在尝试向 MySql 8 0 17 中的现有表添加一列 该列需要包含 UUID 我正在尝试将其设置为默认值 这是我正在执行的语句 ALTER TABLE myTable ADD COLUMN UUID varchar 36 NOT NU
  • 如何将我的应用程序的目标 API 级别从 23 更改为 26

    当我尝试将我的应用程序上传到 Google Play 控制台时遇到问题 API 级别必须为 26 而我的应用程序刚刚使用 23 版本开发 现在我不知道如何从 23 更改此 API 版本到 26 使其正常工作 请帮帮我 Steps Go to
  • Azure Active Directory 组/角色

    我试图弄清楚如何从 Web 门户创建 Windows Azure Active Directory 组和 或角色 我在这里遗漏了一些明显的东西吗 我可以创建用户 并将他们分配给 2 个内置角色 但如何创建新角色 或团体 诚然 我还没有尝试过
  • 如何在 Windows 8 上安装 sqlite 或 postgresql 以进行 ruby​​ on Rails 设置?

    我一直在尝试安装数据库作为 ruby on Rails 设置的一部分 我正在运行 64 位 Windows 8 基于 x64 的计算机 我的ruby版本是2 1 3p242 rails版本是4 0 0 sqlite3版本是3 8 6 pos
  • CloudFormation - 永久删除堆栈

    在 CloudFormation 中删除堆栈后 堆栈保留在 已删除 下的 cloudformation 中 有没有一种方法可以完全删除所有已删除的堆栈并在我的项目上获得干净的云信息 我认为你在 90 天的时间里只能在历史中看到它们 此命令讨
  • 从具有重复元素的向量生成所有独特的组合

    这个问题之前曾被问过 但仅适用于具有非重复元素的向量 我无法找到一个简单的解决方案来从具有重复元素的向量中获取所有组合 为了说明这一点 我在下面列出了一个例子 x lt c red blue green red green red 向量 x
  • 删除编译时的 LESS // 注释

    是否可以配置LESS在通过JS编译时删除 注释 我想从输出的 less 文件中删除它们 Less的单行注释 根据文档所述 应该保持沉默 单行注释在 LESS 中也有效 但它们是 沉默的 它们不会出现在编译后的 CSS 输出中 Hi I m
  • AutoFixture,创建电子邮件地址列表

    我正在编写一些单元测试并有一个名为Account其中有 public Guid AccountId get set public IEnumerable
  • jQuery:检查字段的值是否为 null(空)

    这是检查字段值是否为的好方法null if person data document type value NULL 或者 还有更好的方法 字段的值不能为空 它始终是字符串值 该代码将检查字符串值是否为字符串 NULL 您想检查它是否是空字
  • 将 showModalDialog() 的内容添加到剪贴板 Google 脚本

    当我单击按钮时 我已将格式化数据添加到模态对话框中 我想要的内容showModalDialog 当我单击按钮时也会自动添加到剪贴板 模态是用下面的代码生成的 并且temp是我想要添加到剪贴板的输出 Output to Html var ht
  • 在 C# 汇编版本中使用前导零是否合适?

    我正在为我的 dot net dll 设置程序集版本 汇编版本具有以下格式 主要版本 次要版本 内部版本号 修订版 我将 Verison 设置如下 200 1 1 0 现在我的问题是我是否需要在次要版本 内部版本号和修订号中保留前导零 20
  • 覆盖菜单按钮标签文本颜色 (MacOS SwiftUI)

    我可以覆盖菜单按钮标签的 设置后变暗 颜色吗 下面的 GIF 显示了一个清晰明亮的菜单项 在新选择后会变暗 此系统样式的默认行为 例如 在触控板首选项中 但它不符合可访问性标准 例如 WCAG 要求活动控件中该字体大小的亮度对比度 gt 4
  • 删除ID最小的记录

    当我在 MySQL 中输入此查询时 DELETE FROM myTable WHERE ID SELECT Min ID FROM myTable 我收到以下错误消息 1093 You can t specify target table
  • 枚举本质上不是 IEnumerable 的集合?

    当您想要递归枚举一个分层对象 根据某些条件选择一些元素时 有许多技术示例 例如 扁平化 然后使用 Linq 进行过滤 就像在这里找到的那 些 链接文本 https stackoverflow com questions 141467 rec