Python-like list comprehension in JavaScript using RxJs or Node.js Streams (part 1: RxJS).

Serge Hulne
5 min readApr 15, 2018

--

@ArchibaldBooks

ArchibaldBooks.blog

Foreword

In this very short introduction, Python, JavaScript, and Node.js will not be presented, for the sake of conciseness. It is assumed that the reader seeking to build a conceptual bridge between Python and JavaScript is familiar with these two languages.

Node.js will simply be described as a command-line interpreter for JavaScript. In this article, the terms Node.js (interpreter) and JavaScript (one implementation of ES6) or ES6 (one specification of the JavaScript language) will be used interchangeably.

The problem:

List and dictionaries in Python:

When starting to code with JavaScript after having been coding in Python for years, one might miss some features which are very common in Python, very handy and which allow for a code which is:

  • Concise
  • expressive
  • functional

Another aspect of Python which seems to be missing in JavaScript, at first glance, is generic data structures like:

  • Lists
  • dictionaries

JavaScript offers built-in data structures like Arrays and Maps which seem like good candidates for doing the same job as lists and dictionaries in Python, however, there is no obvious generic (unified) way to iterate over the different JavaScript Arrays and Maps and none at all when the data collection is not of finite size (e.g, coming from a server).

By generic or unified, we mean that JavaScript makes it possible to iterate over collections (iterables) with one unique, standard construct, namely a for loop statement, as in the following examples:

Iteration over a list in Python:

Result:

Iteration over a dictionary in Python:

Result:

Furthermore, Python provides a shorthand for iterating over collections and processing them, which is not merely syntactic sugar, but a simple form of functional programming.

For instance, a shorthand for:

Iterating over a list and doubling the value of the elements:

Can also be rewritten, using a list comprehension:

or using the map function to alter the elements of V:

In this example, the expression :

is the Python expression for an anonymous function (or closure or lambda function), i.e. a nameless function defined locally. A similar construct in JavaScript is called a callback.

List and dictionaries equivalents in JavaScript

The approximate equivalents of the Python list and dictionaries in JavaScript are the Arrays and maps, respectively.

They are typically used as follows:

This 1st way to declare and iterate a vector in JavaScript is reminiscent of C.

a slight variant (with a touch of syntactic sugar a la C++ or Python) is:

Where the temporary variable i is defined locally in the for loop (which is simpler and safer, since its scope gets limited to the for loop which makes use of it).

These two expressions are simple to use and familiar to the practitioner of the dark arts of C, C++, and Java.

A more pythonic way to iterate over an iterable data structure such as a vector in JavaScript is given by the following snippet:

Java-style (or D style or C++11 style) iteration over a vector in JavaScript:

This is more concise, more readable, more expressive and the index variable is implicit.

However the same expression wouldn’t work for a JavaScript object, it would be formulated as:

Please note that the array iteration is:

  • A for-of construct in the case of an Array.
  • A for-in construct in the case of an Object

A for-in construct applied to an Array would get the (successive values of the ) index i of V[i] and not the value of V[i].

The syntax is essentially the same for an associative array or map:

map:

Reformulation of the problem

  • The canonic way to iterate over a collection (Array, map, Object, etc.) in JavaScript varies depending upon the type of collection.
  • The formulation is not functional (expressions cannot be chained).
  • This paradigm offers not list comprehensions, unlike Python.
  • It would be nice to have a uniform way to process iterable collections in JavaScript and to be able to generalize it to objects like files (and other streams of data).
  • One possible solution: Using the RxJs Library.

The RxJS library can be downloaded from its open-source library on GitHub (https://github.com/ReactiveX/rxjs), or installed by the command-line utility which comes with the Node.js interpreter, as follows:

npm installation command for RxJs:

In order to use the RxJs library, one has to refer to it in the code as follows:

Since this article is not a detailed lecture about Python or JavaScript or Node.js or RxJs, the explanations about RxJs will be limited to the potential use thereof to handle iterable collections in JavaScript, in a functional manner similar to list comprehensions in Python.

Here is a very (very) succinct introduction to RxJS.

Basically, RxJs can be used to transform any sequence (finite or non-finite) of data (objects) into an observable, whether they originate from an Array or a JavaScript iterable object or data structure, or from a series of events occurring in a web browser, or whether they are a sequence of data coming from a network or sent by a server.

Once the sequence is transformed into an observable, it can be processed in a standard way, irrespectively of the underlying data structure or data source.

In other words, one we have an observable, one can deal with it very much like the way Python deals with lists (list comprehension, map, filter, reduce, functional programming, etc.)

Let’s first consider a trivial case: an Array.

Here is how to transform an Array into an observable and how to process it, using RxJs:

In this snippet, the expression:

Is an anonymous function (or “callback” ), the equivalent of a lambda function in Python.

RxJs Observables can be constructed from:

  • JavaScript Arrays.
  • JavaScript events
  • JavaScript Objects, Classes, Streams (files, networks)
  • Any sequence of data.

The beauty of it is:

regardless of the underlying source of data or data structure, observables are always handled the same way.

For instance, if one wants to apply a function f(x) to all the elements x of an observable Obs, the syntax is always (irrespectively of the underlying structure from which the observable has been derived):

Which is analogous to the Python expression:

Based on this, we can draw a Python to JavaScript list processing correspondence table:

Python to JavaScript list processing correspondence table

Python to JavaScript list processing correspondence table

Of course, in JavaScript, just like in Python, the map, filter , reduce operations can be chained according to the scheme:

or with an altenative formatting:

Conclusion

With the help of the library RxJs, iterable sequences of data and classic JavaScript data structures can be processed in a manner which is:

  • Simple,
  • Concise,
  • Expressive,
  • Readable,
  • Standard, uniform,
  • Functional,
  • Efficient,
  • With an intuitive syntax which is almost identical to the one used in Python.

References:

Node.js

npm

RxJS

Python (Node.js) vs JavaScript benchmarks

Python doc

--

--

Serge Hulne

Author, scientist (Physics PhD), philosophy, Sci-Fi, thrillers, humor, blues and Irish music, green energy, origins of consciousness.