2013-10-22 43 views
1

我想建立一個方法或擴展方法這需要多個列表,並將它們結合方式如下:如何在Linq中合併多個相同或不同長度的列表?

可以說我有兩個列表:

 int[] list1 = {3, 1, 2}; 
     int[] list2 = {5, 4 }; 

我希望清單數組作爲這樣的結果:

[1,4] 
[1,5] 
[2,4] 
[2,5] 
[3,4] 
[3,5] 

在我所得陣列的列表中的列的數量就會列表 通過量和b來確定其他列需要排序。 行數只是(列表A的長度)*(列表B的長度)*(列表N的長度)

在這個例子中是3 * 2 = 6行。 2列(因爲2個輸入列表)。

用linq做這件事的一個很好的方法是什麼?

謝謝!

+0

有你甚至試着用普通循環和自然算法先解決這個問題?我絕不會使用LINQ來處理這樣複雜的問題。即使'LINQ'可以爲你做到這一點,它的效率就會比正常循環更低效,更難以理解。 ** LINQ不應該被使用在任何成本**。 –

+0

我同意LINQ可能更難以理解,有時效率更低,但我想了解更多。我想過用正常的循環來解決這個問題,但對LINQ方式感到好奇。我的應用程序不會處理巨大的列表,所以我認爲性能不應該成爲問題。 –

+3

@KingKing:這是一個用LINQ解決的完全合理的問題,一點也不復雜。 2元笛卡爾積實際上是*基礎* LINQ序列操作,'SelectMany'。所有的LINQ操作符都可以用'SelectMany'構建;它是序列monad的綁定操作。 n元笛卡爾積當然更復雜一點。 –

回答

2

使用SelectMany

var combinations = list1.SelectMany(i1 => list2.Select(i2 => new[] { i1, i2 })); 

或者如果你喜歡

var combinations = list1.SelectMany(i1 => list2, (i1, i2) => new[] { i1, i2 }); 

如果你想在一個特定的順序的結果,你可以用OrderBy

+0

但是如果我發送2個以上的列表呢?我想有一個方法可以使用n個列表。 –

+1

@AdolfoPerez:這會更復雜。請參閱http://stackoverflow.com/questions/4073713/is-there-a-good-linq-way-to-do-a-cartesian-product – Jon

+0

這正是我需要的。 –

3

嘗試跟進交叉加入

int[] list1 = {3, 1, 2}; 
int[] list2 = {5, 4 }; 

var result = (from l1 in list1 
      from l2 in list2 
      select new [] {l1, l2}).ToList() 
+1

我怎樣才能適應這種方法,可以採取n數量的名單? –

+0

您需要從許多列表中添加儘可能多的子句。 – Tilak

2

幸得這裏@喬恩指着我正確的源和@EricLippert他聰明的解決方案:

public static IEnumerable<IEnumerable<T>> CartesianProduct<T>(this 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 })); 
    } 

http://ericlippert.com/2010/06/28/computing-a-cartesian-product-with-linq/

工程與整數和字符串不錯:

 string[] list1 = {"1", "2", "3"}; 
     string[] list2 = { "4","5" }; 

     var lists = new List<string[]>(){list1,list2}; 

     var result = lists.CartesianProduct(); 
相關問題