Supponiamo che io ho il seguente array (le mie sequenze sono tutti ordinati in ordine crescente, e contenere interi positivi)LINQ Query per identificare i frammenti di una serie
var mySequence = new [] {1, 2, 3, 7, 8, 9, 15, 16, 17};
Voglio scrivere una query LINQ per selezionare il continuo numeri di una serie trattati come un gruppo. Quindi, nell'esempio sopra otterrei {[1, 2, 3], [7, 8, 9], [15, 16, 17]}.
Potrei scrivere una sequenza foreach()
, scorrere attraverso ogni elemento e vedere dove la sequenza sta prendendo un salto e produrre un gruppo lì. Ma c'è qualche modo LINQ di farlo? Potrei essere in grado di spostare il mio codice foreach()
in un nuovo metodo di estensione, quindi il mio codice sembra ancora LINQy, ma mi chiedo se c'è già qualcosa disponibile in System.Linq per quello.
MODIFICA: Avevo creato la mia estensione personale (come segue), ma Me.Name
ha trovato qualcosa di molto intelligente nella sua risposta.
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 };
}
}
}
Questo è un trucco carino per integers-- se il risultato (numero - indice) è 0 allora questo numero è nella posizione dell'array previsto, se il numero è negativo, allora è molto prima di dove è previsto. – Hogan
Cosa succede se la mia sequenza non inizia con 1? supponiamo che questa sia la mia serie var x = new [] {20, 21, 22, 25,26,27, 30,31,32}; – fahadash
@fahadash: funzionerà anche, l'intenzione è che la differenza tra l'indice e il valore sia maggiore se c'è un divario tra i valori. Per quella sequenza: 20-0 = 20, 21-1 = 20, 22 -2 = 20, 25 -3 = 22, 26-4 = 22, ecc. Quindi il valore 'group' salta da 20 a 22 –