【问题标题】:Finding continuous elements in a collection [closed]在集合中查找连续元素 [关闭]
【发布时间】:2014-07-08 07:49:24
【问题描述】:

如果我有 像这样的数组:

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,2,3,4,5 或 5,5,5,5,5?
  • 那么你是想简单地返回5,5,5,5还是找到序列的索引?
  • 请提供您正在寻找该输入的输出的指示
  • 对不起,我的意思是元素 == 5。从索引 4 开始,索引 9 和 12 等有连续的元素集 == 5

标签: c# linq collections


【解决方案1】:

怎么样:

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);
                }
            }
        }
    }
}

【讨论】:

  • 似乎是一个很好的解决方案,但我认为 OP 不会理解其中的任何一个......:)
  • 这是老实说您将如何解决这个问题? :) 如果是这样,这种方法比简单的foreach 比int[] 提供什么?
  • @MarcGravell 你知道我的意思。从那里下来!我不赞成这个答案,因为它真的没有帮助。这很聪明,但没有帮助。理解这个答案需要理解 EqualityComparer、枚举器、扩展方法、yield 运算符、Tuple 类,最后是泛型。
  • @RGraham 您有权查看您的视图;但是,也请随时提供您自己更易于理解的替代答案。因为我很确定这个答案比不存在的答案更有用很多。不,它不需要理解任何这些东西:没有它,代码就可以正常工作。但是,它可能增加对这些事情的理解。了解元组(例如)如何工作的唯一方法是查看它们的使用情况。同上泛型、迭代器块、扩展方法、相等比较器等。OP 可以就这个答案的任何方面提出问题。
  • @rosko 我应该在count++; 旁边添加“将变量计数加一”吗? IMO 代码准确地说明了它已经做了什么;如果对其中的任何部分有具体问题,我将非常乐意详细介绍荒谬的细节,但我不会这样做,除非有一个实际的“你能告诉我{this bit}是什么意思吗? ?”
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-11-07
  • 1970-01-01
  • 2021-10-22
  • 2012-05-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多