2012-04-27 62 views
1

我的問題與此類似:Finding Consecutive Items in List using Linq。除此之外,我想獲得最後連續的沒有空白的項目。例如:使用LINQ獲得最後x個連續項目

2, 4, 7, 8 

輸出

7,8 

又如:

4,5,8,10,11,12 

輸出

10,11,12 

那怎麼可以呢?

+3

爲什麼第二個例子的結果不是10,11,12? – 2012-04-27 23:18:13

+0

最佳答案取決於您的收藏類型。 – Joe 2012-04-27 23:18:29

+2

你爲什麼要用Linq做這個? – Cameron 2012-04-27 23:22:14

回答

10

我從序列假設您要使用一個以上的成員過去的連續序列...所以

{4, 5, 8, 10, 11, 12, 15} 

你期待的順序:

{10, 11, 12} 

我如果最後一個序列只允許有一個成員,則表示要刪除的行,並給出一個序列

{15} 

這裏的LINQ:

new[] {4, 5, 8, 10, 11, 12, 15} 
    .Select((n,i) => new {n, i}) 
    .GroupBy(x => x.n - x.i) //this line will group consecutive nums in the seq 
    .Where(g => g.Count() > 1) //remove this line if the seq {15} is expected 
    .Select(x => x.Select(xx => xx.n)) 
    .LastOrDefault() 

有一個隱藏的假設,這裏說的序列號是按升序排列。如果情況並非如此,則有必要註冊microsoft的擴展方法finding contiguous items in a sequence的權力。讓我知道如果是這樣的話。

+1

+1由數字減去索引是一個非常巧妙的技巧 – MerickOWA 2012-04-28 01:03:35

+0

+1爲聰明的答案(上面的技巧),但我討厭使用這種方法在大型列表考慮'GroupBy'效率低下。 – yamen 2012-04-28 21:31:18

3

這工作,並可能是在這種情況下更容易,比LINQ更高效:

var list = new[] { 2, 4, 7, 8 }; 
List<int> lastConsecutive = new List<int>(); 
for (int i = list.Length - 1; i > 0; i--) 
{ 
    lastConsecutive.Add(list[i]); 
    if (list[i] - 1 != list[i - 1]) 
     break; 
    if(i==1 && list[i] - 1 == list[i - 1]) // needed since we're iterating just until 1 
     lastConsecutive.Add(list[0]); 
} 
lastConsecutive.Reverse(); 
1

我意識到這是兩晚,羅嗦,但是這可能是這裏最快的方法仍然使用LINQ。

測試列表:

var list1 = new List<int> {2,4,7,8}; 
var list2 = new List<int> {4,5,8,10,11,12,15}; 

的方法:

public List<int> LastConsecutive(List<int> list) 
{ 
    var rev = list.AsEnumerable().Reverse(); 

    var res = rev.Zip(rev.Skip(1), (l, r) => new { left = l, right = r, diff = (l - r) }) 
       .SkipWhile(x => x.diff != 1) 
       .TakeWhile(x => x.diff == 1); 

    return res.Take(1).Select(x => x.left) 
       .Concat(res.Select(x => x.right)) 
       .Reverse().ToList(); 
} 

從後到前,並檢查元件成對這一個去,只有從當他們開始是連續服用要素(SkipWhile),直到他們結束連續(TakeWhile)。

然後它做了一些工作,拉出相關的配對數字(從原始列表中剩下的數字,然後所有正確的數字),並將其反轉回去。與命令式版本效率類似,但在我看來,由於LINQ而更易於閱讀。

+0

您的.Zip()語法有問題。它認爲你正在試圖提供三個參數。 – 4thSpace 2012-04-30 17:33:16

+0

我正在粘貼它,它對我來說工作得很好。檢查你的複製。這是.NET 4.0。 – yamen 2012-04-30 19:56:11