生成 IEnumerable(Of T) 元素的所有唯一组合

2024-01-21

这个问题实际上与这个帖子 https://stackoverflow.com/questions/1471558/all-possible-combinations-of-elements,只是我正在寻找 VB.NET (.NET 4) 解决方案。我已经花了很长时间试图想出一个通用的解决方案来解决这个“电源组”问题。

Given:

Dim choices As IEnumerable(Of String) = {"Coffee", "Tea", "Milk", "Cookies"}
Dim choiceSets = choices.CombineAll()

我在找choiceSets成为一个IEnumerable(Of IEnumerable(Of T))这样我就可以做类似的事情:

For each choiceSet in choiceSets
    Console.WriteLine(String.Join(", ", choiceSet))
Next

并得到如下结果:

Coffee
Tea
Milk
Cookies
Coffee, Tea
Coffee, Milk
Coffee, Cookies
Tea, Milk
Tea, Cookies
Milk, Cookies
Coffee, Tea, Milk
Coffee, Tea, Cookies
Coffee, Milk, Cookies
Tea, Milk, Cookies
Coffee, Tea, Milk, Cookies

正如你所看到的,这是每一个不重复从源头组合IEnumerable(Of T)(其中可能有 1 到多个项目 - 本示例只有 4),它根据源中项目的顺序进行操作IEnumerable(Of T),并且列表中的每个项目 >= 前一个项目(就内部项目数而言)IEnumerable(Of T).

无论如何,这不是家庭作业;而是家庭作业。虽然感觉确实如此。

编辑:更新了示例,因此结果看起来不像按字母顺序排序,以强调来源IEnumerable(Of T)使用现有的顺序并添加第四个选择以澄清每组内的排序要求。


这是一个纯粹的 Linq 解决方案,灵感来自 Eric Lippert博客文章 http://blogs.msdn.com/b/ericlippert/archive/2010/06/28/computing-a-cartesian-product-with-linq.aspx关于计算笛卡尔积。我修改了CartesianProduct稍微修改一下方法,使其返回组合:

public static IEnumerable<IEnumerable<T>> Combinations<T>(this IEnumerable<IEnumerable<T>> sequences)
{
    IEnumerable<IEnumerable<T>> emptyProduct = new[] { Enumerable.Empty<T>() };
    return sequences.Aggregate(
        emptyProduct,
        (accumulator, sequence) => 
        from accseq in accumulator 
        // Exclude items that were already picked
        from item in sequence.Except(accseq)
        // Enforce ascending order to avoid same sequence in different order
        where !accseq.Any() || Comparer<T>.Default.Compare(item, accseq.Last()) > 0
        select accseq.Concat(new[] {item})).ToArray();
}

基于此扩展方法,您可以产生所需的结果,如下所示:

IEnumerable<string> items = new[] {"Coffee", "Tea", "Milk"};
IEnumerable<IEnumerable<string>> result =
    Enumerable.Range(1, items.Count())
        .Aggregate(
            Enumerable.Empty<IEnumerable<string>>(),
            (acc, i) =>
                acc.Concat(Enumerable.Repeat(items, i).Combinations()));

(它连接 1、2...N 个项目的所有组合)

请注意,这可能不是一个非常有效的解决方案,但我认为这是 Linq 的一个有趣的用法......


编辑:这是一个新版本Combinations保持原始顺序的方法:

public static IEnumerable<IEnumerable<T>> Combinations<T>(this IEnumerable<IEnumerable<T>> sequences)
{
    var indexedSequences = sequences.Select(seq => seq.Select((item, idx) => new IndexedItem<T>(item, idx)));
    IEnumerable<IEnumerable<IndexedItem<T>>> emptyProduct = new[] { Enumerable.Empty<IndexedItem<T>>() };
    var indexedResult =
        indexedSequences.Aggregate(
            emptyProduct,
            (accumulator, sequence) => 
            from accseq in accumulator 
            // Exclude items that were already picked
            from item in sequence.Except(accseq)
            // Enforce ascending order of indexes to avoid same sequence in different order
            where !accseq.Any() || item.Index > accseq.Last().Index
            select accseq.Concat(new[] {item})).ToArray();
    return indexedResult.Select(seq => seq.Select(i => i.Item));
}

class IndexedItem<T>
{
    public IndexedItem(T item, int index)
    {
        this.Item = item;
        this.Index = index;
    }

    public T Item { get; private set; }
    public int Index { get; set; }
}

可能比以前的版本效率更低,但它完成了工作......

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

生成 IEnumerable(Of T) 元素的所有唯一组合 的相关文章

  • 确定哪个进程锁定了文件

    我有一个在本地运行良好的单元测试 但上传到 TeamCity 构建服务器时失败 并显示 该进程无法访问该文件 因为它正在被另一个进程使用 在我在测试中做任何事情之前 我检查设置是否有文件 存在 如果存在尝试删除它 这会失败并出现相同的错误
  • string.Empty 与 null。您使用哪一个?

    最近工作的同事告诉我不要使用string Empty设置字符串变量时但使用null因为它污染了堆栈 他说不做 string myString string Empty but do string mystring null 真的有关系吗 我
  • Directory.Delete 之后 Directory.Exists 有时返回 true ?

    我有非常奇怪的行为 我有 Directory Delete tempFolder true if Directory Exists tempFolder 有时 Directory Exists 返回 true 为什么 可能是资源管理器打开了
  • 确保 StreamReader 不会挂起等待数据

    下面的代码读取从 tcp 客户端流读取的所有内容 并且在下一次迭代中它将仅位于 Read 上 我假设正在等待数据 我如何确保它不会在没有任何内容可供读取时返回 我是否必须设置低超时 并在失败时响应异常 或者有更好的办法吗 TcpClient
  • 如何在加载.NET WinForm应用程序user.config文件时捕获异常?

    有时 在使用默认配置系统的 NET 2 0 WinForm 桌面应用程序中 user config文件将被损坏并且无法再加载 当配置系统尝试加载它时 它会抛出一个System Xml XmlException 抛开 为什么文件首先被损坏 的
  • 当从finally中抛出异常时,Catch块不会被评估

    出现这个问题的原因是之前在 NET 4 0 中运行的代码在 NET 4 5 中因未处理的异常而失败 部分原因是 try finallys 如果您想了解详细信息 请阅读更多内容微软连接 https connect microsoft com
  • 从列表中选择项目以求和

    我有一个包含数值的项目列表 我需要使用这些项目求和 我需要你的帮助来构建这样的算法 下面是一个用 C 编写的示例 描述了我的问题 int sum 21 List
  • 服务 AddJsonOptions .net core 2.1

    以前使用 net 2 0 您可以通过这种方式添加 json 内容 services AddJsonOptions options gt options SerializerSettings ContractResolver new Came
  • Java中的对象池模式

    所以我实现了自己的对象池模式 它工作得很好并且符合预期 从列表中返回我的 老师 对象 并在没有对象时创建它们 我的问题 返回的对象 Teacher 然后需要被转换为它的专门子类之一 例如 生物老师 获得这种功能的最佳方法是什么 编辑 抱歉
  • WM_CLOSE 和 SC_CLOSE 之间的区别

    我只是想知道这两个消息常量之间有什么区别 我应该使用哪一个WndProc重写时的方法 用于处理关闭按钮消息 WM CLOSE http msdn microsoft com en us library windows desktop ms6
  • 在 VB.NET 中将类标记为静态

    正如刚刚在最近的一篇文章中所说question https stackoverflow com questions 135759 why cant i inherit iodirectory and answer https stackov
  • 如何在javascript中计算日出和日落?

    我正在使用appcelerator titan开发一个IOS应用程序 我想让我的应用程序在日出和日落时向用户发送本地通知 解决这个问题的一个好工具是使用 YQL 的雅虎天气 但是 雅虎天气仅供非商业用途 我正在尝试找到一个javascrip
  • 什么是 .NET 程序集?

    什么是 NET 程序集 我浏览了网络 但无法理解其定义 程序集是 net 应用程序的最小部署单元 它可以是一个dll or an exe 它主要有两种类型 私人集会 dll 或 exe 是一个应用程序的专有财产 一般存放在应用程序根文件夹中
  • 泛型和实现 IComparable

    我对泛型非常陌生 我正在尝试编写一个简单的类 它将是泛型的 但也允许对字符串成员变量的一些描述进行排序 目前我有一个基本类 但是当我尝试实现接口成员 CompareTo 时 我在顶部收到一个错误 告诉我它尚未实现 这里有什么问题呢 usin
  • IIS / .Net 只允许对给定用户会话进行单个并发响应

    这是我的问题 我们有一个 Net 4 5 Web 表单应用程序 由于服务器端的大量数据访问和操作 应用程序中的某些页面需要很长时间才能加载 如果用户在页面完成加载之前关闭浏览器选项卡 然后打开新选项卡 则新选项卡中对应用程序的任何请求都将挂
  • Sub New() 在此上下文中无法访问,因为它是“Friend”

    那么这是什么意思以及如何解决它 如果我将 New 关键字放在下面的行中 则会出现此消息 如果删除它 我会在运行时收到错误消息 提示我需要使用 New 我究竟做错了什么 Dim oPS As AeccPointStyle New AeccPo
  • 使用对象初始化语法的操作顺序

    我使用对象初始值设定项语法设置属性的顺序是否以完全相同的顺序执行 例如 如果我这样做 var s new Person FirstName Micah LastName Martin IsLoaded true 每个属性都会以相同的顺序设置
  • 任务和异步任务之间的区别

    C 提供了两种创建异步方法的方法 Task static Task
  • 从 SQL 语句中检索元数据(表名)

    我使用的是 Visual Studio 2008 我创建了一个 Winforms 应用程序 并且尝试从 SQL 语句中提取表名 con new SqlConnection connString String queryString Sele
  • 如何检查日期时间是否发生在今天?

    有没有比下面的代码更好的 net 方法来检查 今天 是否发生了 DateTime if newsStory WhenAdded Day DateTime Now Day newsStory WhenAdded Month DateTime

随机推荐