J'ai besoin d'implémenter une version de Je pense que cela soit construit Exemple fort> p> devrait donner p > combinelatst code> (je l'appellerai
withlaest code> ici) qui appelle le sélecteur pour chaque élément de gauche et le dernier élément de la à droite. Il ne devrait pas pousser pour les articles sur le bon changement seulement.
observable.create code> ou une combinaison d'extensions existantes n'est pas particulièrement importante; Je vais faire une méthode d'extension "boxée" de toute façon. P>
var lr = right.ObserveOn(Scheduler.TaskPool).Latest();
left.Select(l => l + " " + lr.First()).Dump();
6 Réponses :
Voici le chemin hacky en utilisant Create - ne l'a pas réellement construit, MEA CULPA s'il ne fonctionne pas réellement :)
public static IObservable<TRet> WithLatest<TLeft, TRight, TRet>( this IObservable<TLeft> lhs, IObservable<TRight> rhs, Func<TLeft, TRight, TRet> sel) { return Observable.Create<TRet>(subj => { bool rhsSet = false; bool deaded = false; var latestRhs = default(TRight); Action onDeaded = null; var rhsDisp = rhs.Subscribe( x => { latestRhs = x; rhsSet = true; }, ex => { subj.OnError(ex); onDeaded(); }); var lhsDisp = lhs .Where(_ => deaded == false && rhsSet == true) .Subscribe( x => subj.OnNext(sel(x, latestRhs)), ex => { subj.OnError(ex); onDeaded(); }, () => { subj.OnCompleted(); onDeaded(); }); onDeaded = () => { deaded = true; if (lhsDisp != null) { lhsDisp.Dispose(); lhsDisp = null; } if (rhsDisp != null) { rhsDisp.Dispose(); rhsDisp = null; } }; return onDeaded; }); }
Je reçois "1 0", "2 0" pour mon exemple.
Whoops, ma clause Where était mauvaise, essayez-la maintenant
maintenant c'est juste "3 2" i> - quelle est la solution correcte en fonction de l'exigence: seulement pousser pour la gauche i>
J'ai aussi eu le même besoin d'un J'ai fait la solution une "surcharge" de Combinelatst de code> qui "ne pousse que pour la gauche".
observable.Sample code> , parce que c'est ce que la méthode fait:
Il échantillon un source code> (à droite) avec un échantillonneur code> (à gauche), avec la capacité supplémentaire de fournir un
RESUMECTEnector code> (comme dans Combinelatst). < / p>
Utilisation pour l'exemple ci-dessus: droite.sample (gauche, (r, l) => l + "" + r) .Dump (); code> il produit "3 2" qui est imo correct
Basé sur la solution choisie par l'auteur Post, je pense qu'il y a une solution encore plus simple utilisant distinctuntilchanged : ou même p> Si vous ne vous souciez que de valeurs distinctes de Leftsource code> p> p>
Vous pouvez le faire en utilisant les opérateurs existants.
Func<int, int, string> selector = (l, r) => l + " " + r; var query = right.Publish(rs => left.Zip(rs.MostRecent(0), selector).SkipUntil(rs));
Publish code> nous assure que nous ne vous abonnez à ce que
à droite code> une fois et partagez l'abonnement parmi tous les abonnés à
rs code>. p> li>
mostrecent code> tourne un
iobservable
ienumerable
zip code> entre
iobservable
ienumerable code> émet une valeur à chaque fois que l'observable émet une valeur. li>
SPAPUNTIL code> saute les paires
(l, r) code> qui se produisent avant
droite code> émet une valeur. P>
ul> p>
J'ai fait un opérateur RX pour le projet aujourd'hui qui fait cela.
Voici mes solutions: P>
public static IObservable<Tuple<TSource, TTarget>> JoinLeftSoft<TSource, TTarget>( this IObservable<TSource> source, IObservable<TTarget> right) { return source .Select(x => new Tuple<object, TSource>(new object(), x)) .CombineLatest(right, (l, r) => new Tuple<object, TSource, TTarget>(l.Item1, l.Item2, r)) .DistinctUntilChanged(t => t.Item1) .Select(t => new Tuple<TSource, TTarget>(t.Item2, t.Item3)); }
sur le dernier system.reactive em>, nous pouvons utiliser Le résultat serait inférieur correctement. p> withLatestFrom code> méthode d'extension.
Vous souhaitez effectuer ces combinaisons W / existants uniquement ou une implémentation utilisant
créer () code> une option?
Votre exemple ne correspond pas à ce que je m'attendais à votre description. Le premier élément renvoyé dans votre exemple semble être déclenché par un changement de droite observable. Devrait-il
WASLATEST code> déclencheur sur la première droite s'il y a déjà des éléments de gauche?
Voir «CombinaisonLaest» dans Ma réponse ici - très modèle similaire.
@Gideon engelberth: d'accord. Cela m'a laissé de perplexe aussi. Selon la description, l'algorithme devrait donner uniquement "3 2" seulement.
Pouvez-vous écrire votre réponse comme une réponse plutôt qu'une modification à la question?