使用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