2011-05-13 3 views
2

J'ai une liste de numéros et je voudrais sélectionner une fenêtre glissante d'une certaine taille:Liste fenêtre coulissante

List<double> lst = {3,78,24,25,634,25,478,24}; 
int WindowSize = 4; 

index = 0: return {3}; 
index = 1: return {3,78}; 
index = 2: return {3,78,24}; 
index = 3: return {3,78,24,25}; 
index = 4: return {78,24,25,634}; 
index = 5: return {24,25,634,25}; 
index = 6: return {25,634,25,478}; 
index = 7: return {634,25,478,24}; 

Ce n'est pas si difficile d'un concept, mais je suis en train pour le faire avec les méthodes d'extension .Skip() .Take(). Existe-t-il un moyen plus simple de sélectionner les entrées WindowSize avant un élément au lieu d'essayer de trouver le point de départ et d'obtenir les entrées WindowSize suivantes? J'essaie de trouver un moyen plus facile de faire cela avec linq que d'avoir toutes les vérifications de limites requises avec Skip() et Take().

Vous pouvez inverser la liste, puis faire un Count() - index puis un Take() mais cela ne semble pas efficace.

Répondre

3

Je suppose que cela nécessiterait une vérification minimale limitée - juste des vérifications de base de la santé mentale. Voir si cela fonctionne

IEnumerable<double> GetWindow(List<double> lst, int index, int windowSize) { 
    if(index >= lst.Length){ 
     // Throw proper exception 
    } 
    return lst.Skip(index-windowSize).Take(Math.Min(index,windowSize)); 
} 
+2

vous pouvez simplement utiliser Skip (index windowSize), les valeurs négatives sont simplement ignorées et traitées comme 0 – Alexander

+0

@Alexander Oui, vous avez raison - Je l'ai raté. Corrigée. Merci. – YetAnotherUser

0

Si vous voulez seulement obtenir une fenêtre, votre réponse acceptée semble appropriée. Mais pour itérer plus d'une fenêtre, je voudrais aller avec quelque chose comme ceci:

public static IEnumerable<IEnumerable<TSource>> Window<TSource>(
    this IEnumerable<TSource> source, int size) 
{ 
    var q = new Queue<TSource>(size); 

    foreach (var value in source) 
    { 
     if (q.Count >= size) 
      q.Dequeue(); 
     q.Enqueue(value); 
     yield return q; 
    } 
} 
Questions connexes