-
Notifications
You must be signed in to change notification settings - Fork 7.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
combineWithMostRecent #405
Comments
Actually, |
But what if o1 emits two equal items in sequence? |
If that is part of your problem we're discussing the distinct operator here. #395 (comment) |
Maybe this is a |
Join is hardly ever used, and the semantics are subtle. and because of all the functions you need to pass pretty nasty if you don't have groupBy query comprehension syntax. But implementing it would be a fun task for anyone that wants to dig down to the next level of detail. Watch http://channel9.msdn.com/Series/Rx-Workshop/Rx-Workshop-7-Reactive-Coincidence first ...
|
This means that maybe it's a good idea to add |
I have similar problem - came up with:
but noticed sample() doesn't really sample input - it doesn't emit last value multiple times when no change occured between timer, causing zip operation to get out of sync. Isn't that a bug (or at least serious documentation problem) with sample()? marcin |
I agree, that's inconsistent: |
How about this? Observable.combineLatest(a, b, { x, y -> [x, y] })
.distinctUntilChanged({ tuple -> tuple[0]})
.distinctUntilChanged({ tuple -> tuple[1]})
.toBlockingObservable().forEach({ v-> println(v)}) |
Regarding issue1: How to get combineWithMostRecent/enrich behavior: What if the source Observable Regarding issue2: Is the behavior of |
The |
Note: The [I've reread this thread because this question was asked on stackoverflow]. |
Would something like the following work: observableA.combineWithMostRecentFrom(observableB) This would different from Then the |
Guys, guys, we need to solve this one. I've been using this "combineWithMostRecent" or "enrich" (I call it "combinePrev") many times in an Android project in production. It's very useful. Basically what we need is the asymmetric version of combineLatest. I used to have an implementation of it based on My implementation of the operator with join is this: /**
* Similar to combineLatest, except it joins the latestitems from the two source
* observables only when the first observable emits an item.
*
* first: ------f----f-------------f--------------f----|>
* second: ---s1----------s---s--s3-----s-s-s-s4--------|>
* result: ------R1---R1------------R3-------------R4---|>
*
* @param first
* The first source Observable
* @param second
* The second source Observable
* @param combineFunction
* the aggregation function used to combine the items emitted by the source
* Observables
* @return an Observable that emits items that are the result of combining the items
* emitted by the source Observables by means of the given function
*/
public static <TFirst, TSecond, R> Observable<R> combinePrev(
final Observable<TFirst> first,
final Observable<TSecond> second,
final Func2<TFirst, TSecond, R> combineFunction)
{
final Observable<TSecond> hotSecond = second.publish().refCount();
return first.join(hotSecond, new Func1<TFirst, Observable<Object>>() {
public Observable<Object> call(final TFirst it) {
return Observable.<Object>empty();
}
}, new Func1<TSecond, Observable<TSecond>>() {
public Observable<TSecond> call(final TSecond it) {
return hotSecond;
}
}, combineFunction);
} But I just figured a much simpler implementation based only on map and switch, basically this:
|
What was expected? It emits the last item in a given time window if something was emitted. If nothing was emitted then nothing is emitted at the end of the time window. http://reactivex.io/RxJava/javadoc/rx/Observable.html#sample(long,%20java.util.concurrent.TimeUnit) |
Sure, let's get it solved. Once #1905 is confirmed let's add a new operator marked with |
So we just need to find a proper name for it. I prefer shorter names, but |
It's not quite The static To confirm, here we want to combine every value from one Observable with the latest or most recent of another, correct? It feels like an instance method of It ends up being very similar to Does this have a proper name in Haskell, Scala or some other functional language that I'm unaware of? @headinthebox Your input on this would be helpful. |
Let me think what the shortest way to implement this is using the existing combinators; cant believe it is very long but I am jetlagged ;-) |
This appears to be producing the expected results: public class CombineWhenOther {
public static void main(String[] args) {
PublishSubject<Integer> source = PublishSubject.create();
BehaviorSubject<Integer> other = BehaviorSubject.create();
source.concatMap(e -> other.take(1).map(f -> e + f))
.subscribe(System.out::println, Throwable::printStackTrace,
() -> System.out.println("Done"));
source.onNext(1);
other.onNext(10);
other.onNext(20);
other.onNext(30);
source.onNext(2);
source.onNext(3);
other.onNext(40);
source.onCompleted();
}
} But both sources are hot, and since we don't have multicast(), I don't know how to convert a general other Observable to BehaviorSubject with the stable API. |
Sorry, with this implementation
I forgot to mention that B must be hot.
It is sample as in
If we could afford renaming existing operators, one suggestion is Another thing to keep in mind is that this new operator is an instance method, and shouldn't have a static version. Because of the asymmetric behavior, there should be one source Observable that commands the emission of the resulting Observable. If we take that into consideration, we could name it
Another insight is that since the My humble suggestions are then either |
That's exactly what I was looking for.
For example, if I sample an audio signal
emits an element every 50 milliseconds, no matter when But I agree that the way RxJava understands "sample" also makes sense, and it's well explained in the docs what happens, so I'm not saying we should change anything.
I think |
I agree this is a very useful operator, and, @staltz , I like your map - switch implementation. Just for cross-reference, I have already raised this issue (#912) some time ago. Naming the new operator indeed is difficult now that |
Or, what about
|
@dvtomas if we would use |
Or |
@staltz Sorry, can't see it. My mind is already too deeply connected with my interpretation.. Also, I work in scala, the combineFunction would probably be absent, it would be just @akarnokd That sounds reasonable wrt to |
So to clarify, which of |
Now implemented in RxJS as The implementation can be roughly
Or a state machine like I did in RxJS. |
http://stackoverflow.com/questions/28580490/rxjava-how-to-emulate-withlatestfrom Some one please implement it? |
👍 I have had 4 separate instances of need of this in the last two weeks that I felt dirty working around! |
I'll do this. |
👍 👍 |
See #2760 for the proposed name and behavior. |
This issue can be closed. |
Damn it, I couldn't stop thinking about this all night.
produces the output
It would simpler if you don't need the triggers value.
produces the output
|
@abersnaze or just A.switchMap({a -> hotB.map({b -> [a, b]})}) |
I had to change the variable names to grok it. Much better than mine. |
I'm looking for an operation which does the following:
Whenever Observable o1 emits an item, combine this item with the most recent item of Observable o2.
Illustration:
I can't find a nice way of doing this.
Can anyone help me?
Or do we need to add a new operation to
rx.Observable
?The text was updated successfully, but these errors were encountered: