2013-08-20 78 views
2

是否有一種簡單的方法可以使用linq在每個索引中創建一個相同大小的列表並創建其最小/最大值的新列表?我的意思是如何在相同指數比較項目,並挑選其中之一是最大或最小喜歡這裏:使用LINQ將幾個列表合併爲一個

List<List<int>> Some2dList = new List<List<int>> 
       { new List<int> { 1, 2, 3, 4, 5 }, 
        new List<int> { 5, 4, 3, 2, 1 } } ; 
List<int> NewList = new List<int>(5); 

for(int i=0; i< 5; i++) 
{ 
    int CurrentHighest=0; 
    for(int j=0; j<2; j++) 
    { 
     if (Some2dList[j][i] > CurrentHighest) 
      CurrentHighest = Some2dList[j][i]; 
    } 
    NewList.Add(CurrentHighest); 
} 
//Which gives me {5,4,3,4,5} 

我已經簡化這些循環看clearlier。我知道我可以使用Concat和GroupBy,然後在每個中選擇Max,但對於沒有鍵值的簡單類型和類我無法弄清楚。

編輯:我更加精確。示例中的列表是手動分配的,但我在詢問解決方案,對於任何數量的比較列表來說都是靈活的。此外,列表總是相同的大小。

+0

他們總是相同的每個條目的數量? (i,e'new double [x,5]') – Sayse

+0

是的,不需要檢查值是否存在。所有列表具有相同的大小。 – Tarec

回答

3

有點不正常,但似乎工作。它假定有一個名單,雖然

Enumerable.Range(0, Some2dList.FirstOrDefault().Count) 
    .Select(columnIndex => 
     Some2dList.Max(row => row[columnIndex])) 
    .ToList(); 
+0

謝謝你,作品像一個魅力。 – Tarec

+0

不用擔心,正如我所說的,它假定至少有一個列表,否則您將在FirstOrDefault – Sayse

+2

+1上得到NRE。這可能是矩形外殼的最佳解決方案。請注意,在這段代碼中'FirstOrDefault()'不比'First'好,因爲在任何一種情況下它都會拋出空引用。 –

4

這應該做你在找什麼:

List<int> newList = Some2dList[0].Select((x, column) => Math.Max(x, Some2dList[1][column])).ToList(); 

訣竅正在選擇的過載,可以讓你有你與在lambra表達工作項目的索引:這使得可能比較位於同一索引中的兩個不同列表中的兩個項目。顯然,如果它是您正在尋找的最小值,請使用Math.Min而不是Math.Max。

只有一件事,我認爲這兩個子列表具有相同數量的元素。

+0

謝謝。當然,它對2個列表非常有用,但如果我有更多的列表呢? – Tarec

+1

+1我認爲這是2元素數組情況下的答案。請注意,顯示默認的一個字母命名有時很難用變量名稱的「x,y」來讀取 - 像「index」或「column」而不是「y」會更好。 –

6

列表列出和列表的大小沒有限制可以是任何長度。

List<List<int>> Some2dList = new List<List<int>>{ 
     new List<int> { 1, 2, 3, 4, 5 }, 
     new List<int> { 5, 4, 3, 2, 1 }, 
     new List<int> { 8, 9 } 
     }; 
var res = Some2dList.Select(list => list.Select((i, inx) => new { i, inx })) 
      .SelectMany(x => x) 
      .GroupBy(x => x.inx) 
      .Select(g => g.Max(y=>y.i)) 
      .ToList(); 
+0

+1匿名用法。 –

+1

+1。花式LINQ用於非矩形選項。請注意,如果性能很重要,由於創建了許多中間集合,它可能不是正確的方法。 –

+0

@AlexeiLevenkov當然。如果性能很重要,那麼最好編寫一個非Linq版本。 – I4V