2012-01-04 72 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 ; 
}