Question

Je conçois un cadre interne simple pour le traitement des données de séries chronologiques. Étant donné que LINQ est mon marteau-jouet actuel, je veux tout toucher.

Je souhaite implémenter des méthodes dans la classe TimeSeries (Select (), Where (), etc.) afin de pouvoir utiliser la syntaxe LINQ pour gérer les données de séries chronologiques

Certaines choses sont simples, par exemple (de x dans A, sélectionnez x + 10), donnant une nouvelle série chronologique.

Quelle est la meilleure conception de syntaxe pour combiner deux séries chronologiques ou plus? (de a dans a de b en b sélectionnez a + b) n'est pas génial, car il exprime une boucle imbriquée. Peut-être que certains rejoignent? Cela devrait correspondre à rejoindre la variable de temps implicite. (Ce que j'ai en tête correspond à la fonction 'zip' de lisp)

MODIFIER: Des éclaircissements sont nécessaires.

Une série chronologique est une sorte de fonction dépendant du temps, par exemple. cotations boursières. Une combinaison de séries temporelles pourrait correspondre à la différence entre deux cours boursiers, en fonction du temps.

Stock1.MyJoin(Stock2, (a,b)=>a-b)

est possible, mais cela peut-il être exprimé clairement en utilisant une syntaxe LINQ? Je compte implémenter moi-même les méthodes LINQ dans la classe MyTimeSeries .

Était-ce utile?

La solution

Si je comprends bien la question, vous souhaitez joindre plusieurs séquences en fonction de leur position dans la séquence?

Il n'y a rien dans la classe System.Linq.Enumerable à cela car les méthodes Join et GroupJoin sont toutes deux basées sur joindre des clés. Cependant, par coïncidence, j’ai écrit une méthode PositionalJoin dans ce seul but quelques jours en arrière, utilisé comme dans votre exemple:

sequenceA.PositionalJoin(sequenceB, (a, b) => new { a, b });

La sémantique de la méthode montrée ci-dessous est qu’elle n’exige pas que les séquences soient de même longueur, mais il serait trivial de la modifier pour l’exiger. J’ai également commenté où la vérification des arguments devrait être telle qu’elle utilisait nos classes d’aides internes.

public static IEnumerable<TResult> PositionalJoin<T1, T2, TResult>(
    this IEnumerable<T1> source1, 
    IEnumerable<T2> source2, 
    Func<T1, T2, int, TResult> selector)
{
    // argument checking here
    return PositionalJoinIterator(source1, source2, selector);
}

private static IEnumerable<TResult> PositionalJoinIterator<T1, T2, TResult>(
    IEnumerable<T1> source1, 
    IEnumerable<T2> source2, 
    Func<T1, T2, TResult> selector)
{
    using (var enumerator1 = source1.GetEnumerator())
    using (var enumerator2 = source2.GetEnumerator())
    {
        bool gotItem;
        do
        {
            gotItem = false;

            T1 item1;
            if (enumerator1.MoveNext())
            {
                item1 = enumerator1.Current;
                gotItem = true;
            }
            else
            {
                item1 = default(T1);
            }

            T2 item2;
            if (enumerator2.MoveNext())
            {
                item2 = enumerator2.Current;
                gotItem = true;
            }
            else
            {
                item2 = default(T2);
            }

            if (gotItem)
            {
                yield return selector(item1, item2);
            }
        }
        while (gotItem);
    }
}

Je ne sais pas si c'est exactement ce que vous recherchez, mais j'espère de l'aide.

Autres conseils

Union sonne comme la bonne voie à suivre - aucune expression de requête ne prend en charge, mais je pense que cela exprime ce que vous voulez dire.

Vous voudrez peut-être consulter les classes basées sur les plages dans MiscUtil qui peuvent être bien utilisé pour les temps. Combiné avec un peu de méthode d'extension amusant, vous pouvez faire:

foreach (DateTime day in 19.June(1976).To(DateTime.Today).Step(1.Day()))
{
    Console.WriteLine("I'm alive!");
}

Je ne suggère pas que cela devrait remplacer ce que vous faites, mais simplement pour que vous puissiez prendre quelques idées pour le rendre encore plus net. N'hésitez pas à contribuer également:)

De mon projet NExtension :

public static IEnumerable<TResult> Zip<T1, T2, TResult>(
    this IEnumerable<T1> source1, 
    IEnumerable<T2> source2, 
    Func<T1, T2, TResult> combine)
{
    if (source1 == null)
        throw new ArgumentNullException("source1");
    if (source2 == null)
        throw new ArgumentNullException("source2");
    if (combine == null)
        throw new ArgumentNullException("combine");

    IEnumerator<T1> data1 = source1.GetEnumerator();
    IEnumerator<T2> data2 = source2.GetEnumerator();
    while (data1.MoveNext() && data2.MoveNext())
    {
        yield return combine(data1.Current, data2.Current);
    }
}

La syntaxe est la suivante:

Stock1.Zip(Stock2, (a,b)=>a-b)

Bjarke, jetez un coup d’œil à NEsper, c’est une application open source de traitement des événements complexes qui effectue, entre autres choses, des requêtes chronologiques de type SQL. Vous pouvez soit apprendre comment ils l'ont fait, soit peut-être même utiliser leur code pour atteindre votre objectif. lien ici http://esper.codehaus.org/about/nesper/nesper.html

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top