7
votes

Y a-t-il un équivalent au F # SEQ.Windowed dans C #?

Je travaille sur certains C # Code traitant de problèmes tels que des moyennes mobiles, où j'ai souvent besoin de prendre une liste / iEnumerable et de travailler sur des morceaux de données consécutives. Le module F # SEQ a une excellente fonction, vitrée, qui prend une séquence, retourne une séquence de morceaux d'éléments consécutifs.

Est-ce que c # a une fonction équivalente en dehors de la boîte avec LINQ?


1 commentaires

L'utilisateur qui a fourni la réponse acceptée a été admis qu'il était faux, vous voudrez peut-être envisager de choisir un autre maintenant.


4 Réponses :


9
votes

Vous pouvez toujours simplement appeler seqmodule.Windowed de C #, il vous suffit de référencer fshaarp.core.dll . Les noms de fonction sont également légèrement mangés, vous appelez donc fenêtré plutôt que fenêtré , de sorte qu'il convient aux conventions C # Capitalization


3 commentaires

Ici, ici, ça fait ça tout le temps! SEQ.SINGLETON, FSHARPSET, vous le nommez. Quand je dois coder en C #, je viens souvent à l'aide du F # stdlib. Comment pourrais-je vivre sans ça!


C'est seqmodule.Windowed en fait.


J'aime trouver une réponse ici que j'ai déjà prélevé et édité, mais j'ai complètement oublié.



2
votes

Vous pouvez toujours rouler votre propre (ou traduire celui de F # noyau):

public static IEnumerable<T[]> Windowed<T>(this IEnumerable<T> list, int windowSize)
{
    //Checks elided
    var arr = new T[windowSize];
    int r = windowSize - 1, i = 0;
    using(var e = list.GetEnumerator())
    {
        while(e.MoveNext())
        {
            arr[i] = e.Current;
            i = (i + 1) % windowSize;
            if(r == 0) 
                yield return ArrayInit<T>(windowSize, j => arr[(i + j) % windowSize]);
            else
                r = r - 1;
        }
    }
}
public static T[] ArrayInit<T>(int size, Func<int, T> func)
{
    var output = new T[size];
    for(var i = 0; i < size; i++) output[i] = func(i);
    return output;
}


6 commentaires

Remplacez l'appel à arrayinit avec var barr = nouveau t [Windowsize]; pour (int j = 0; j et r = r - 1 avec r - et - dans mes tests de toute façon - il était légèrement plus rapide que SEQ.Windowed < / code>.


SEQ.Windowed Utilise Zerocreeeunchecked , mais il ignore simplement la validation du paramètre Taille (c.-à-d. si la taille <0 Invalidarg .. . ). Cela n'évite pas la vérification des limites. Cela fait à la discrétion de la jière, je crois.


@Daniel, ravi de voir quelqu'un a pris l'appât :) Je ne peux pas avoir vos résultats cependant. Si je fais var list = énumérable.Range (0, 100000); var sw = stopwatch.startnew (); int compte = liste.Windowed (15) .Count (); sw.stop (); et ensuite la même chose avec microsoft.fsharp.collections.seqmodule.windowed (sur une nouvelle plage), le C # prend toujours environ deux fois plus long ...


Exécutez-vous le C # dans le débogueur? Exécutez les deux versions en mode de sortie.


@Daniel, aurait dû penser à cela! C # toujours plus lent que f # pour moi cependant, mais pas deux fois plus long. Pastebin.com/tvgfffaM


C # et Les versions F # effectuent presque de manière identique sur l'idéone. Le C # est négligablement plus lent, mais l'idéone utilise Mono. Mes tests originaux étaient sous Windows.



1
votes

Le Extensions réactives Avoir quelques opérateurs pour aider à cela, comme tampon et fenêtre . Les extensions interactives, qui peuvent être trouvées dans la branche expérimentale, ajoutent celles-ci et un nombre important d'opérateurs supplémentaires à LINQ.


0 commentaires

2
votes

La réponse de John Palmer est géniale, voici un exemple basé sur sa réponse.

var numbers = new[] {1, 2, 3, 4, 5}; 
var windowed = SeqModule.Windowed(2, numbers);


0 commentaires