使用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++;
}
}
使用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++;
}
}
不,我認爲這並不容易。你有的代碼很容易理解和簡潔,我不會用linq來重構它。確保你測試了一下,因爲你可能會在最後一個循環中出現界限錯誤。
但在Linq中,您如何訪問下一個值以將其與當前值進行比較? – marseilles84 2012-01-04 20:32:50
試試這個:
var set = values.Where((value, i) => i < (values.Length - 1) ? values[i] == values[i + 1] : false);
編輯:
對不起,忘了補充set.Count()來很容易地與得到的結果:-)
是的,你可以這樣做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
對,每個對包含一個值及其後繼者。
從那裏,它只是一個計數哪都一樣:)
注意,在討論的序列將兩次評估,這樣你就不會要任何東西這是懶洋洋地做到這一點,對事評估,或兩次評估時不會得出相同的結果。
存在一個非常巧妙的解決辦法:
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
鑑於值是一個數組,你可以這樣做:
int duplicates = values.Skip(1).Where((n, i) => n == values[i]).Count();
你可以這樣說:
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 ;
}
列表是否應該換行?例如,數字7會發生什麼?你比較第一個值(1)還是不做任何事情? – Icarus 2012-01-04 20:30:06
是的,不要擔心最後一個值。 – marseilles84 2012-01-04 20:30:36
你需要在你的循環條件btw中檢查'value.Length - 2',否則當你嘗試訪問'values [f + 1]時,你會掉到數組的末尾並且得到一個索引超出界限的異常。 '最後一次 – rejj 2012-01-04 20:31:32