1

Theoretically it should be possible to implement any RxJS operator (except just() and flatMap()) through flatMap(). For instance map() can be implemented as

function map(source, selector) {
  return source.flatMap(x => Rx.Observable.just(selector(x)));
}

How to implement merge() through flatMap()? (avoiding mergeAll() too, of course)

isherwood
  • 58,414
  • 16
  • 114
  • 157
André Staltz
  • 13,304
  • 9
  • 48
  • 58
  • What is this theory you're referring to? I don't think this assumption holds true at all, even though map and filter are easily done. – raimohanska Jun 19 '15 at 12:51
  • 1
    I have heard before `flatMap` and `just` are the only ones needed to implement other operators, but this is the only quotation I have related to this "theory" https://twitter.com/headinthebox/status/610836009278803969 – André Staltz Jun 19 '15 at 13:38
  • Does that mean it's cheating to use Rx.Observable.create? – paulpdaniels Jun 19 '15 at 15:12
  • Hm, it's interesting approach. I wonder if implementation using those two methods only will be much less effective than current one (inside Rx). Definitely it will be simpler and much more understandable. – Eryk Napierała Jun 19 '15 at 20:45
  • i stand corrected :) didn't know about the array returning variant of flatMap. – raimohanska Jun 20 '15 at 15:54

1 Answers1

4

It looks possible if you take advantage of the fact that flatMap can also take array return values.

Rx.Observable.prototype.merge = function(other) {
  var source = this;
  return Rx.Observable.just([source, other])
           //Flattens the array into observable of observables
           .flatMap(function(arr) { return arr; })
           //Flatten out the observables
           .flatMap(function(x) { return x; });
}

EDIT 1

Using RxJS 6 and the pipe syntax

import {of} from 'rxjs'
import {flatMap} from 'rxjs/operators'

function merge (other) {
  return source => of([source, other]).pipe(
           //Flattens the array into observable of observables
           flatMap(arr => arr)
           //Flatten out the observables
           flatMap(x => x)
         );
}

const {timestamp, map, flatMap, take} = rxjs.operators;
const {interval, of: just} = rxjs;

const source1 = interval(2000).pipe(
  timestamp(),
  map(x => "Interval 1 at " + x.timestamp + " w/ " + x.value)
)

const source2 = interval(3000).pipe(
  timestamp(),
  map(x => "Interval 2 at " + x.timestamp + " w/ " + x.value)
)

function mergeFromFlatMap (other) {
  return source => just([source, other]).pipe(
    flatMap(arr => arr),
    flatMap(seq => seq)
  )
}

source1.pipe(
  mergeFromFlatMap(source2),
  take(20)
).subscribe(console.log.bind(console));
<script src="https://unpkg.com/rxjs/bundles/rxjs.umd.min.js"></script>
paulpdaniels
  • 18,395
  • 2
  • 51
  • 55