3

For example, in Python we have such a convenient tool — instead of writing like

values = [1,2,3,4,5]
altered_values = []
for v in values:
    altered_values.append(v*25)

We could just write

altered_values = [v*25 for v in values]

Are such one-liners possible in Javascript?

yxfxmx
  • 665
  • 1
  • 6
  • 13
  • 2
    This is a list comprehension, not a generator expression. – Matthias May 05 '15 at 12:48
  • As an alternative in JS you could use `Array#map`: `altered_values = values.map(function (v) { return v*25; });` and with ES6 you can get it shorter: `altered_values = values.map(v => v*25);` – James Allardice May 05 '15 at 12:53
  • @Matthias yep, my fault. edited. – yxfxmx May 05 '15 at 12:54
  • @JamesAllardice any difference in performance? – yxfxmx May 05 '15 at 12:55
  • 1
    @yxfxmx - `map` is likely to be slower than a normal `for` loop but it's unlikely to make any real-world difference. Both should be significantly faster than using a comprehension and transpiling to ES5. – James Allardice May 05 '15 at 12:58
  • Does this answer your question? [Make Javascript do List Comprehension](https://stackoverflow.com/q/4964456/90527) – outis Dec 18 '21 at 00:55

2 Answers2

5

Babel used to support syntax for comprehensions but no longer does. None of the modern browsers support comprehensions anymore either. Also, as of 2017, it doesn't look like there are plans to re-add support anytime in the near future. With ES6, however, you could use generator functions to sort of simulate the functionality of a python-like list comprehension: Consider this example:

const someArray = [1,2,3,4,5,6];
const evens = [...(function*() { for(let x of someArray) if(x%2 == 0) yield x;})()]
console.log(evens);
// [2,4,6]

This would work in browsers that support the current standard of ES6. There is a proposal right now for arrow generators that would make this syntax a little shorter.

I definitely wouldn't use this in production code unless you (and all those who are working on the code) are very comfortable with using generators as iterators. Also its kind of ugly. It does give you an advantage over map, however. If you implemented this same thing using map, then you would also need to remember to compact afterwards. This is because map will return undefined for all the uneven numbers. That would look like:

const someArray = [1,2,3,4,5,6];
const evens = someArray.map(x => {
  if(x % 2 === 0) return x;
});

Of course filter would work better in this example.
You can find the docs on generator functions here.

Joseph Ditton
  • 998
  • 8
  • 7
4

Short answer: no.

Long answer: kind of, under very special circumstances: Array comprehensions are a very similar tool, which might be present in the ECMAScript 7 edition of the language (that's the one after the next). With them you can write:

var altered_values = [for (v of values) v*25];

Currently they are only supported by the Spidermonkey engine, ie. Firefox.

Edit: as JamesAllardice points out below, they are also available for use via the Babel transpiling library, which means you can practically use them in any browser.

doldt
  • 4,466
  • 3
  • 21
  • 36