2012-12-16 69 views
1

我想弄清楚如何使用C#创建单个连接列表,源自3个单独的列表。例如:连接3单词列表

List 1: Ugly, Pretty 
List 2: Dogs, Carts, Pigs 
List 3: Rock, Suck 

输出:

Ugly Dogs Rock 
Ugly Dogs Suck 
Ugly Cats Rock 
Ugly Cats Suck 
Ugly Pigs Rock 
Ugly Pigs Suck 
Pretty Dogs Rock 
Pretty Dogs Suck 
Pretty Cats Rock 
Pretty Cats Suck 
Pretty Pigs Rock 
Pretty Pigs Suck 

我知道这只是个嵌套循环,但我不能找出部分是如何使用List串每个列表。

回答

4
var list = from s1 in list1 
      from s2 in list2 
      from s3 in list3 
      select s1 + " " + s2 + " " + s3; 
+0

我建议在select语句中使用别的东西,因为目前你有多余的连接,因此内存使用。 – abatishchev

+1

@abatishchev其实不会有问题。当连接2或3个字符串时,编译器会生成对'String.Concat(str1,str2,str3)'的调用,它使用'FastAllocateString'来创建新的字符串。这比在String.Format调用中创建新的StringBuilder效率更高。但在这种特殊情况下,OP希望有空格分隔的字符串,所以这就是为什么应该使用格式的原因。 –

+0

@lazyberezovsky - 我认为同样的事情,并测试它:连接它与'a +“”+ b +“”+ c'大约比'String.Format'快30%。 – JulianR

4

它不是笛卡儿的产品吗?

var r = from i1 in list1 
     from i2 in list2 
     from i3 in list3 
     select new { i1, i2, i3 }; 
     // or String.Format("{0} {1} {2}", i1, i2, i3); 
3
List<string> list1 = new List<string>(){ "Ugly", "Pretty"}; 
List<string> list2 = new List<string>(){ "Dogs", "Carts", "Pigs"}; 
List<string> list3 = new List<string>(){ "Rock", "Suck"}; 

var result = from s1 in list1 
      from s2 in list2 
      from s3 in list3 
      select new[] { s1, s2, s3 }; 

foreach (var item in result) 
{ 
    Console.WriteLine(String.Join(",", item)); 
} 

如果你正在寻找一个更通用的解决方案,不仅为3所列出您可以尝试埃里克利珀的解决方案

foreach (var item in new[] { list1, list2, list3 }.CartesianProduct()) 
{ 
    Console.WriteLine(String.Join(",", item)); 
} 

public static partial class MyExtensions 
{ 
    // Eric Lippert’s Blog 
    // Computing a Cartesian Product with LINQ 
    // http://blogs.msdn.com/b/ericlippert/archive/2010/06/28/computing-a-cartesian-product-with-linq.aspx 
    public static IEnumerable<IEnumerable<T>> CartesianProduct<T>(this IEnumerable<IEnumerable<T>> sequences) 
    { 
     // base case: 
     IEnumerable<IEnumerable<T>> result = new[] { Enumerable.Empty<T>() }; 
     foreach (var sequence in sequences) 
     { 
      var s = sequence; // don't close over the loop variable 
      // recursive case: use SelectMany to build the new product out of the old one 
      result = 
       from seq in result 
       from item in s 
       select seq.Concat(new[] { item }); 
     } 
     return result; 
    } 
} 
+0

L.B. - 所以,如果我想要结果到一个新的列表并打印到一个新的文本框,我会做这样的事情吗? textBox_MergeListResults.Text = string.Join(“\ r \ n”,这是什么?); – Jeagr

+0

@Jeagr'textBox_MergeListResults.Text = String.Join(Environment.NewLine,result.Select(x => String.Join(“,”,x)));' –

+1

完美工作!谢谢。 – Jeagr