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?