使用linq和这段代码做同样的事情会更容易吗? (检查并查看有多少值等于下面的值):
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 :(得分:2)
是的,您可以使用.NET 4中的Zip
轻松完成此操作:
var count = values.Zip(values.Skip(1), (x, y) => new { x, y })
.Count(pair => pair.x == pair.y);
结合Zip
和Skip(1)
的诀窍需要一点点让你的头脑,但它是一个非常整洁的。基本上,您从一系列n
值开始,结果是一对n - 1
对,每个对都包含一个值及其后继值。
从那里开始,只需计算相同的对数:)
请注意,有问题的序列将被评估两次,因此您不希望对任何懒惰评估的内容执行此操作,或者在评估两次时不会给出相同的结果。
答案 1 :(得分:1)
不,我不认为这更容易。您拥有的代码易于理解和简洁,我不会用linq重构它。确保你测试一下,因为你可能会在最后一个循环中遇到一个越界错误。
答案 2 :(得分: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
答案 3 :(得分:0)
试试这个:
var set = values.Where((value, i) => i < (values.Length - 1) ? values[i] == values[i + 1] : false);
编辑:
抱歉,忘了添加set.Count()来获得结果: - )
答案 4 :(得分:0)
鉴于值在数组中,您可以这样做:
int duplicates = values.Skip(1).Where((n, i) => n == values[i]).Count();
答案 5 :(得分: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 ;
}