Załóżmy, że mam następujące array (moje sekwencje są sortowane w kolejności rosnącej i zawierają liczby całkowite dodatnie)LINQ kwerendy do identyfikacji fragmentów w serii
var mySequence = new [] {1, 2, 3, 7, 8, 9, 15, 16, 17};
Chcę napisać kwerendę LINQ wybierz ciągła liczby w serii traktowanej jako grupa. W powyższym przykładzie otrzymam {[1, 2, 3], [7, 8, 9], [15, 16, 17]}.
Mogę napisać sekwencję foreach()
, przechodzić przez każdy element i zobaczyć, gdzie sekwencja wykonuje skok i zgrupować tam grupę. Ale czy jest jakiś sposób na zrobienie tego LINQ? Być może będę w stanie przenieść mój kod foreach()
do nowej metody rozszerzenia, więc mój kod nadal wygląda LINQy, ale zastanawiam się, czy jest już coś dostępnego w System.Linq.
EDYCJA: Stworzyłem własne rozszerzenie (w następujący sposób), ale Me.Name
wymyślił coś bardzo inteligentnego w swojej odpowiedzi.
internal class Sequence
{
public int Start { get; set; }
public int End { get; set; }
}
internal static class EnumerableMixins
{
public static IEnumerable<Sequence> GroupFragments(this IEnumerable<int> sequence)
{
if (sequence.Any())
{
var lastNumber = sequence.First();
var firstNumber = lastNumber;
foreach(var number in sequence.Skip(1))
{
if (Math.Abs(number - lastNumber) > 1)
{
yield return new Sequence() { Start = firstNumber, End = lastNumber };
firstNumber = lastNumber = number;
}
else
{
lastNumber = number;
}
}
yield return new Sequence() { Start = firstNumber, End = lastNumber };
}
}
}
Jest to ładny trick integers-- jeśli wynik (numer - indeks) wynosi 0, wtedy ta liczba znajduje się w oczekiwanym miejscu tablicy, jeśli liczba jest ujemna, to jest to dużo wcześniej, niż się spodziewano. – Hogan
Co się stanie, jeśli moja sekwencja nie rozpocznie się od 1? załóżmy, że to jest moja seria var x = new [] {20, 21, 22, 25,26,27, 30,31,32}; – fahadash
@Fahadash: to również zadziała, intencją jest, aby różnica między indeksem a wartością była większa, jeśli istnieje luka między wartościami. Dla tej sekwencji: 20-0 = 20, 21-1 = 20, 22 -2 = 20, 25 -3 = 22, 26-4 = 22, itd. Tak więc wartość "grupy" skacze od 20 do 22 –