-
Notifications
You must be signed in to change notification settings - Fork 3k
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
Document special cases of reduce operator usage for certain pattern #2323
Comments
Would the rest operator not be sufficient in this case? source.reduce((array, d) => [...array, doSomething(d)], []) |
Besides paul's great example, in this particular case it sounds like you could use the const items = Observable.of(1, 2, 3).toArray();
items.subscribe(arr1 => {
items.subscribe(arr2 => {
console.log(arr1 !== arr2);
// true (they are not same array instance)
});
}); But one could argue for other mutable data structures than arrays. In that case, I'm not aware of any super clean way to do this with the existing operators. (others may think of a pattern) There's const source = Observable.of(10, 20, 30); // from wherever
const items = Observable.defer(() =>
source
.reduce((arr, item) => {
arr.push(item);
return arr;
}, [])
)
// do other stuff like
.filter(d => d.length > 0); It's not as trivial as I'll let some others chime in here. |
ooooo I just thought of a new solution: const items = Observable.of(10, 20, 30)
.reduce((arr = [], item) => {
arr.push(item);
return arr;
}, undefined); Notice that we're passing in literally the value of |
Thanks, Jay - seems you exactly understood my issue and put it in better words than I would have been able to! The toArray solution does not really work for me, because in my case, each iteration may reduce zero to multiple values. Paul's solution does indeed offer an elegant approach, but I somehow doubt th at I can trust a Javascript engine to optimize out the unnecessary copies to avoid the quadratic scaling. I leave it up to you guys to close this issue if you decide that the solution proposed by Jay is good enough. I could imagine that the use-case is common enough to at least document this clever solution along with the reduce function. |
Edit: he deleted his comment, here's a copy for context:
@masaeedu yeah, see my comment below the example
We want a brand new instance for every subscription, instead of sharing the same instance. |
@jayphelps Yeah, sorry. I hadn't read the original post carefully enough and hadn't understood the problem. I get it now. It seems like the only sensible way to bake this in to |
If I had to make an educated guess, the core library itself prolly won't get If you don't like the Observable.prototype.collect = function (seedFactory, accumulator) {
return this.reduce(
(acc = seedFactory(), ...rest) => accumulator(acc, ...rest),
undefined
);
};
Observable.of(1, 2, 3)
.collect(() => [], (arr, item) => {
arr.push(item);
return arr;
}); If microperf is critical, it's easy enough to create a more performant version--chances are extremely high that your app won't know the difference. Certainly an argument could be made that documenting these patterns would be super helpful for people who may not realize them. Anyone can jump in and help. |
I believe we probably won't going to have this as separate operator set, but feeling worth to mention as some kind of examples - changed issue topic. |
Closing this. I think that reduce is now adequately documented, and we don't need another operator here. |
According to http://reactivex.io/documentation/operators/reduce.html, ReactiveX defines a reduce operator for nearly all languages, a 'collect' operator for only a few of them, not including Javascript.
'collect' seems to a a very valuable to RxJS. Using 'reduce' to collect items into an Array is rather awkward. Specifically, I cannot find a way to make sure that the empty array required as initial value is not reused for multiple subscriptions of the observable.
Please implement the 'collect' operator for RxJS in such a way that an new empty array is created as initial value for each subscription.
The text was updated successfully, but these errors were encountered: