0

I have one interesting question. Maybe anybody know how could I implement a method like a http://ramdajs.com/docs/#xprod. I have one solution which I found:

let as = [1, 2, 3];
let bs = ['a', 'b', 'c'];

Rx.Observable.for(bs, b => {  
  return Rx.Observable.for(as, a => Rx.Observable.just([a, b]));  
}).toArray().subscribe(x => {
  console.log(x.sort((a, b) => a[0] - b[0]));
});
Noah Freitas
  • 17,240
  • 10
  • 50
  • 67
xgrommx
  • 461
  • 3
  • 15
  • 1
    So, does your solution work? If yes, what is your question? – Bergi Jul 09 '15 at 18:39
  • I need a more better solution. Now I should accumulate all data to a sequence and to sort in a subscribe. But I think that exists another approach. – xgrommx Jul 09 '15 at 19:09
  • Wait, if you want the transposed order, just swap `as` and `bs` in those `.for` loops? – Bergi Jul 09 '15 at 19:41
  • Oh! Maybe I tired today. Don't see a trivial thing. Yes, probably you are right =) `let as = [1, 2, 3]; let bs = ['a', 'b', 'c']; Rx.Observable.for(as, b => { return Rx.Observable.for(bs, a => Rx.Observable.just([b, a])); })./*toArray().*/subscribe(x => { console.log(x/*.sort((a, b) => a[0] - b[0])*/); });` – xgrommx Jul 09 '15 at 20:46
  • 1
    FWIW: while you know I'm a *huge* proponent of Rx, if you already have these as Arrays (which you'd have to for this sort of action), it's probably much more efficient/performant to do this with the arrays directly, then convert the result to an Observable. – Ben Lesh Jul 13 '15 at 18:24
  • Yes you are right. But Matthew Podwysocki shown me how can I create it. This is just the Cartesian product of sets https://github.com/Reactive-Extensions/RxJS/issues/807 – xgrommx Jul 13 '15 at 23:15

1 Answers1

0

I agree with Ben Lesh's comment above that, unless there's something async going on, you probably don't need to use an Observable.

A plain ES5, array-based solution (which is equivalent to Matt Podwysocki's inner map solution) could look like:

var as     = [1, 2, 3],
    bs     = ['a', 'b', 'c'];
as.flatMap = flatMap;

var product = as.flatMap(pairWithAllBs);

// pairWithAllBs :: Number -> [[Number, String]]
function pairWithAllBs(a) {
    return bs.map(function (b) {
        return [a, b];
    });
}

// flatMap :: @[a], (a -> [b]) -> [b]
// JS does not have a built-in flatMap function.
function flatMap(fn) {
    return Array.prototype.concat.apply([], this.map(fn));
}

In ES7, using array comprehensions, we should be able to just do:

[for (a of as) for (b of bs) [a, b]];
Noah Freitas
  • 17,240
  • 10
  • 50
  • 67