2012-01-04 70 views
0

使用linq執行與此代碼相同的操作更容易嗎? (檢查並查看有多少個值等於下面的值):使用linq查找連續2個值

int[] values = {1,2,3,3,5,6,7}; 

int counter=0; 
for (int f =0; f< values.Length-1; f++) 
{ 
    if(values[f]==values[f+1]) 
    { 
    counter++; 
    } 
} 
+0

列表是否應該換行?例如,數字7會發生什麼?你比較第一個值(1)還是不做任何事情? – Icarus 2012-01-04 20:30:06

+0

是的,不要擔心最後一個值。 – marseilles84 2012-01-04 20:30:36

+0

你需要在你的循環條件btw中檢查'value.Length - 2',否則當你嘗試訪問'values [f + 1]時,你會掉到數組的末尾並且得到一個索引超出界限的異常。 '最後一次 – rejj 2012-01-04 20:31:32

回答

1

不,我認爲這並不容易。你有的代碼很容易理解和簡潔,我不會用linq來重構它。確保你測試了一下,因爲你可能會在最後一個循環中出現界限錯誤。

+0

但在Linq中,您如何訪問下一個值以將其與當前值進行比較? – marseilles84 2012-01-04 20:32:50

0

試試這個:

var set = values.Where((value, i) => i < (values.Length - 1) ? values[i] == values[i + 1] : false); 

編輯:

對不起,忘了補充set.Count()來很容易地與得到的結果:-)

2

是的,你可以這樣做Zip在.NET 4:

var count = values.Zip(values.Skip(1), (x, y) => new { x, y }) 
        .Count(pair => pair.x == pair.y); 

組合Zip和0的特技需要一點點頭腦,但它是一個非常整潔。基本上,您從一系列n值開始,結果是一對n - 1對,每個對包含一個值及其後繼者。

從那裏,它只是一個計數哪都一樣:)

注意,在討論的序列將兩次評估,這樣你就不會要任何東西這是懶洋洋地做到這一點,對事評估,或兩次評估時不會得出相同的結果。

1

存在一個非常巧妙的解決辦法:

var list = new[] { 1, 2, 3, 3, 5, 6, 7, 7 }; 
var pairs = SeqModule.Pairwise(list); 
var count = pairs.Count(p => p.Item1 == p.Item2); 

這需要你引用的程序集FSharp.Core並使用using Microsoft.FSharp.Collections;。或者,您可以實施Pairwise方法作爲擴展方法,從而避免使用其他程序集。

對於任何人誰威力感興趣的F#,這裏是一個解決方案:

let lst = [1;2;3;3;5;6;7;7] 
let count = lst |> Seq.pairwise 
       |> Seq.filter (fun (x, y) -> x = y) 
       |> Seq.length 
0

鑑於值是一個數組,你可以這樣做:

int duplicates = values.Skip(1).Where((n, i) => n == values[i]).Count(); 
0

你可以這樣說:

private static int CountDoubles(IEnumerable<int> Xs) 
{ 
    int? prev = null ; 
    int count = Xs.Count(curr => { 
    bool isMatch = prev.HasValue && prev == curr ; 
    prev = curr ; 
    return isMatch ; 
    }) ; 

    return count ; 
} 

但這並不比您的原始版本更簡單也不乾淨。我會稍微調整你的,但::

public static int CountDoubles(int[] Xs) 
{ 
    int n = 0 ; 

    for (int i = 1 ; i < Xs.Length ; ++i) 
    { 
    n += (Xs[i-1] == Xs[i] ? 1 : 0) ; 
    } 

    return n ; 
}