更新:雖然Patrick在評論中指出在技術上並非「linq查詢」,但此解決方案可重複使用,靈活且通用。
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
要獲得第二組,更改:
var consecutiveGroups = numbers.FindConsecutiveGroups((x) => x > 10, 3);
要:
var consecutiveGroups = numbers.FindConsecutiveGroups((x) => x > 10, 3).Skip(1).Take(1);
更新2在我們的職業調整之後由於numbers數組中的項數越來越大,下面的實現要快得多。
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查詢。 –
@Patrick,在技術上它不是一個「LINQ查詢」,但如果您刪除使用System.Linq的;行,這將無法正常工作,因此它是Linq,而不是以查詢的形式。而且這樣更靈活。以可重複使用的方式解決問題。 – Jim