列出所有可能的组合

时间:2013-06-08 06:02:14

标签: c# algorithm

我有一个与该组合相关的问题。

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

例如:Black Pant 34W 30L,Black Pant 38W 32L,White Pant 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}}

P.S。棘手的部分是我不知道客户将为此产品分配多少选项。选项的计数可能只有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

感谢您的帮助!

1 个答案:

答案 0 :(得分:5)

正如评论中所述,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();

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