我遇到的情况是,我需要找到以下双打列表列表的所有排列:
List<double> A = new List<double>(){ 1, 2, 3};
List<double> B = new List<double>(){ 10, 20, 30};
List<double> C = new List<double>(){ 100, 200, 300};
需要给我:
{(1,10,100),(1,10,200),(1,10,300),(1,20,100),(1,20,200),(1,20,300)...}
我可以为固定数量的列表执行此操作,但我希望通用解决方案的灵活性(和整洁性)。我找到了处理单个列表排列的答案,但没有从每个列表中选择一个选项,如上所示。
答案 0 :(得分:0)
扩展Ani的评论:我也使用Eric Lippert的解决方案来做这种事情。 (我只是将它用于单元测试所有可能的少量数据组合。)
using System;
using System.Collections.Generic;
using System.Linq;
namespace Demo
{
public static class Program
{
static void Main(string[] args)
{
var a = new List<double> { 1, 2, 3 };
var b = new List<double> { 10, 20, 30 };
var c = new List<double> { 100, 200, 300 };
var lists = new List<List<double>> {a, b, c};
foreach (var combination in Combine(lists))
{
Console.WriteLine(asString(combination));
}
}
static string asString(IEnumerable<double> data)
{
return "(" + string.Join(",", data) + ")";
}
/// <summary>
/// Calculates the n-ary Cartesian Product (i.e. all possible combinations) of items taken from any
/// number of sequences.
/// </summary>
/// <typeparam name="T">The type of the items in the sequences.</typeparam>
/// <param name="sequences">The sequences to combine.</param>
/// <returns>An enumerator that yields all possible combinations of items.</returns>
/// <remarks>
/// This code is taken from http://blogs.msdn.com/b/ericlippert/archive/2010/06/28/computing-a-cartesian-product-with-linq.aspx
///
/// If the sequences are ABC and 123, the output will be A1, A2, A3, B1, B2, B3, C1, C2, C3.
/// </remarks>
public static IEnumerable<IEnumerable<T>> Combine<T>(IEnumerable<IEnumerable<T>> sequences)
{
IEnumerable<IEnumerable<T>> emptyProduct = new[] { Enumerable.Empty<T>() };
return sequences.Aggregate(
emptyProduct,
(accumulator, sequence) =>
from accseq in accumulator
from item in sequence
select accseq.Concat(new[] { item }));
}
}
}