【问题标题】:List all the possible combinations [duplicate]列出所有可能的组合[重复]
【发布时间】:2013-06-04 11:57:27
【问题描述】:

我有一个关于组合的问题。

我实际上正在开发一个电子商务网站,并且我有一个允许客户创建产品变体的功能。

例如:黑裤 34W 30L,黑裤 38W 32L,白裤 34W 30l。这些被定义为产品变体。

假设我的裤子有 3 个选项,分别是颜色、腰围和长度。

我现在有 3 个列表。

ListA = {"black", "white", "red"} //For the color
ListB = {30,32,34,36,38} //For the waist
ListC ={28,30,32,34} //For the length

我的问题是如何列出所有可能的组合?

我想要的结果应该是 {{black,30,28},{black,30,30},{black,30,32},{white,34 ,30}}

附:棘手的部分是我不知道客户会为这个产品分配多少选项。选项的计数可能只有 1,这是最简单的;可能超过 3 个...

问题已解决

因为我们不知道我们会有多少选择。因此,我们不知道要使用多少个 for 循环。换句话说,它变成了一个典型的笛卡尔积。

有关更多信息,您可以阅读这两个链接。 http://www.interact-sw.co.uk/iangblog/2010/07/28/linq-cartesian-1 http://blogs.msdn.com/b/ericlippert/archive/2010/06/28/computing-a-cartesian-product-with-linq.aspx

感谢您的帮助!

【问题讨论】:

  • 你看过其他电子商务系统是如何做到的吗? dashCommerce 有一个类似的选项来从产品变体生成 SKU。
  • 我确实有一个 NopCommerce 并从中学到了一些想法。
  • 非常感谢你们俩。非常感谢你的线索。笛卡尔积是关键字!

标签: c# algorithm


【解决方案1】:

正如 cmets 中所述,Eric Lippert 有一篇名为 Computing a Cartesian Product with LINQ 的博客文章解释了如何解决您的问题。您需要一个扩展方法来计算笛卡尔积:

public static IEnumerable<IEnumerable<T>> CartesianProduct<T>(this IEnumerable<IEnumerable<T>> sequences) {
  IEnumerable<IEnumerable<T>> result = new [] { Enumerable.Empty<T>() };
  foreach (var sequence in sequences) {
    var localSequence = sequence;
    result = result.SelectMany(
      _ => localSequence,
      (seq, item) => seq.Concat(new[] { item })
    );
  }
  return result;
}

然后您需要一系列序列来执行产品。在您的情况下,您的序列中同时包含字符串和整数,因此公共基本类型 T 必须是 Object

var sequences = new[] {
  new Object[] { "black", "white", "red" },
  new Object[] { 30, 32, 34, 36, 38 },
  new Object[] { 28, 30, 32, 34 }
};

要计算笛卡尔积,您只需调用扩展方法:

var result = sequences.CartesianProduct();

当您枚举结果时,它是动态计算的(懒惰地)。如果您希望创建列表列表,则需要在 Concat 之后以及从扩展方法返回 result 之前调用 ToList()

【讨论】:

  • 谢谢哥们,你拯救了世界!
  • @Eric Lippert 如何使用表达式树进行笛卡尔积计算?我认为它比 LINQ 功能版本强大得多:stackoverflow.com/a/31376699/2746390
  • 我必须将 ToList() 放在 Concat 之后才能正常工作。 (.NET 框架 4.6)
  • @ReinierDG:关于何时使用ToList的信息应该在我回答的最后一段。
猜你喜欢
  • 2018-06-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多