使用Linq在列表中查找连续项 [英] Finding Consecutive Items in List using Linq

查看:80
本文介绍了使用Linq在列表中查找连续项的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

说我有以下整数数组:

int[] numbers = { 1, 6, 4, 10, 9, 12, 15, 17, 8, 3, 20, 21, 2, 23, 25, 27, 5, 67,33, 13, 8, 12, 41, 5 };

我如何编写一个Linq查询来查找3个大于10的连续元素?另外,如果我可以指定我要说的是此类元素的第一,第二,第三等组,那就太好了.

How could I write a Linq query that finds 3 consecutive elements that are, say, greater than 10? Also, it would be nice if I could specify I want say the first, second, third etc. group of such elements.

例如,Linq查询应该能够识别: 12,15,17作为第一组连续元素 第二组23,25,27 第三组67,33,13

For example, the Linq query should be able to identify: 12,15,17 as the first group of consecutive elements 23,25,27 as the second group 67,33,13 as the third group

如果我指定我希望第二组包含3个连续元素,则查询应返回第二组.

The query should return to me the 2nd group if I specify I want the 2nd group of 3 consecutive elements.

谢谢.

推荐答案

更新:虽然从技术上讲不是Patrick指出的"linq查询",但此解决方案可重用,灵活且易于使用.通用的.

UPDATE: While not technically a "linq query" as Patrick points out in the comments, this solution is reusable, flexible, and generic.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication32
{
    class Program
    {
        static void Main(string[] args)
        {
            int[] numbers = { 1, 6, 4, 10, 9, 12, 15, 17, 8, 3, 20, 21, 2, 23, 25, 27, 5, 67,33, 13, 8, 12, 41, 5 };

            var consecutiveGroups = numbers.FindConsecutiveGroups((x) => x > 10, 3);

            foreach (var group in consecutiveGroups)
            {
                Console.WriteLine(String.Join(",", group));
            }
        }        
    }

    public static class Extensions
    {
        public static IEnumerable<IEnumerable<T>> FindConsecutiveGroups<T>(this IEnumerable<T> sequence, Predicate<T> predicate, int count)
        {
            IEnumerable<T> current = sequence;

            while (current.Count() > count)
            {
                IEnumerable<T> window = current.Take(count);

                if (window.Where(x => predicate(x)).Count() >= count)
                    yield return window;

                current = current.Skip(1);
            }
        }
    }
}

输出:

12,15,17
23,25,27
67,33,13 

要获得第二组,请更改:

To get the 2nd group, change:

var consecutiveGroups = numbers.FindConsecutiveGroups((x) => x > 10, 3);

收件人:

var consecutiveGroups = numbers.FindConsecutiveGroups((x) => x > 10, 3).Skip(1).Take(1);

更新2 在我们的生产用途中对此进行了调整之后,随着numbers数组中的项数越来越大,下面的实现要快得多.

UPDATE 2 After tweaking this in our production use, the following implementation is far faster as the count of items in the numbers array grows larger.

public static IEnumerable<IEnumerable<T>> FindConsecutiveGroups<T>(this IEnumerable<T> sequence, Predicate<T> predicate, int sequenceSize)
{
    IEnumerable<T> window = Enumerable.Empty<T>();

    int count = 0;

    foreach (var item in sequence)
    {
        if (predicate(item))
        {
            window = window.Concat(Enumerable.Repeat(item, 1));
            count++;

            if (count == sequenceSize)
            {
                yield return window;
                window = window.Skip(1);
                count--;
            }
        }
        else
        {
            count = 0;
            window = Enumerable.Empty<T>();
        }
    }
}

这篇关于使用Linq在列表中查找连续项的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆