Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are the differences between Array map and rxjs map

I was wondering what the map on both rxjs and array works the same way. What are the differences between the uses of both the array map method and rxjs map operator?

like image 784
Dhiru Avatar asked Oct 11 '18 06:10

Dhiru


3 Answers

Array.map transforms each element of a single array.

console.log( [ 1, 2, 3 ].map(x => x * x) )
// log: [ 1, 4, 9 ]

In general, RXJS Observables are more like a stream of data, but each data is its own entity.

You may choose to store arrays in your Observable, but still, each array is treated like a single entity. Every time you call Subject#next, you're providing an entirely new array. In this scenario, there is no equivalent to Array#push with RXJS, because RXJS doesn't care that the content of the Observable happens to be an array.

// Observable that holds an array as its type
const subject: Subject<number[]> = new Subject<number[]>();
subject.pipe(
  // the value here is a full array
  map(arr => arr.map(x => x * x))
).subscribe(arr => console.log(arr));

subject.next([ 1, 2, 3 ]);
// log: [ 1, 4, 9 ]

subject.next([ 7, 8, 9 ]);
// log: [ 49, 64, 81 ]

* Bonus : You can kinda make something act more like an array if you set up a ReplaySubject. This implementation of Subject literally replays all the data that was given to it (or a subset based on how you instantiate it). As you'll see though, the limitation to this would be that you can only push onto the end, and you have to create a new subscription to see the entire "array", but it's an interesting thought experiment nonetheless.

const subject: ReplaySubject<number> = new ReplaySubject<number>();
subject.next(1);
subject.next(2);
subject.next(3);

const transformed: Observable<number> = subject.pipe(
  map(x => x * x)
);

transformed.pipe(first()).subscribe(x => console.log(x));
// log: 1
// log: 4
// log: 9

subject.next(9);
transformed.pipe(first()).subscribe(x => console.log(x));
// log: 1
// log: 4
// log: 9
// log: 81
like image 119
Jeff Fairley Avatar answered Oct 14 '22 02:10

Jeff Fairley


Their functioning is quite the same, they give a new Array / Observable (respectively) with each element transformed according to (usually) a transformation function (the technical computer science name would be a projection), taking as parameter the modified object and its index.

Array.map is part of the prototype of Array natively. You can use it on any array in any JavaScript environment. (provided you didn't mess up the Array.prototype, of course)

Observable.map must be imported. (For RxJS 6 : import { map } from 'rxjs/operators';, for older versions : import { map } from 'rxjs/add/operator/map'


There is a small but significant difference

Array.map transformation function has access to the whole array being transformed (the third parameter in the projection function).

Exemple :

     let arr = ['a', 'b', 'c'];
     let arrResult = arr.map(
       (elem, index, wholeArray) => 'element ' + elem + ' was in position ' + index + ' in array ' + wholeArray);
     console.log(arrResult);

This is "of course" not possible (generally speaking) in the context of Observable since the "whole list" of emitted value is probably not known at the time each element is emitted.


On the opposite, there is another small difference : Observable.map operator take an (optional) thisArg parameter, so the transformation function has access to some specified context.

I think this other difference is quite insignificant : Array.map doesn't need this, because it is a function and you can also specify your own "this" with the various ways of calling functions in JavaScript. (I don't find a nice link for this part, anyone who want to add a reference for this in this answer is welcome).

Also, I would find interesting to be challenged on that last point anyway.

like image 4
Pac0 Avatar answered Oct 14 '22 02:10

Pac0


RxJS is for working with Observables and native map is for Arrays. Thats the only diffrence I can think of.

like image 2
Code Spirit Avatar answered Oct 14 '22 02:10

Code Spirit