查找集合中的连续元素

时间:2014-05-20 07:13:33

标签: c# linq collections

如果我有  像这样的数组:

int[] nums = {1,2,3,4,5,5,5,5,1,5,5,51,5,5,12,5,5,5};

我想使用Linq返回一个数组,该数组定义每个起始索引,其中2个或更多条目与前一个索引相同。所以使用上面的数组我希望返回数组。

4,9,12,15 数组元素恰好是5,但值并不重要。

这是可能的还是我应该使用foreach循环来使事情更容易阅读?

1 个答案:

答案 0 :(得分:2)

怎么样:

From index 4, value 5 repeated 4 time(s)
From index 9, value 5 repeated 2 time(s)
From index 12, value 5 repeated 2 time(s)
From index 15, value 5 repeated 3 time(s)

代码:

using System;
using System.Collections.Generic;

static class Program
{
    static void Main()
    {
        int[] nums = { 1, 2, 3, 4, 5, 5, 5, 5, 1,
                     5, 5, 51, 5, 5, 12, 5, 5, 5 };
        foreach(var block in nums.FindBlocks())
        {
            Console.WriteLine(
                "From index {0}, value {1} repeated {2} time(s)",
                block.Item1, block.Item2, block.Item3);
        }
    }
    public static IEnumerable<Tuple<int, T,int>> FindBlocks<T>(
              this IEnumerable<T> source)
    {
        var eq = EqualityComparer<T>.Default;
        using(var iter = source.GetEnumerator())
        {
            if(iter.MoveNext())
            {
                T last = iter.Current;
                int startIndex = 0, count = 1, index = 1;
                while(iter.MoveNext())
                {
                    var cur = iter.Current;
                    if(eq.Equals(last,cur))
                    {
                        count++;
                    }
                    else
                    {
                        if(count >= 2)
                        {
                            yield return Tuple.Create(startIndex, last, count);
                        }
                        count = 1;
                        last = cur;
                        startIndex = index;
                    }
                    index++;
                }
                if (count >= 2)
                {
                    yield return Tuple.Create(startIndex, last, count);
                }
            }
        }
    }
}