Does JavaScript support array/list comprehensions like Python?

Question:

I’m practicing/studying both JavaScript and Python. I’m wondering if Javascript has the equivalence to this type of coding.

I’m basically trying to get an array from each individual integer from the string for practice purposes. I’m more proficient in Python than JavaScript

Python:

string = '1234-5'

forbidden = '-'

print([int(i) for i in str(string) if i not in forbidden])

Does Javascript have something similar for me to do above?

Asked By: A K

||

Answers:

Not directly, but it’s not hard to replicate.

var string = "1234-5";

var forbidden = "-";

string.split("").filter(function(str){
    if(forbidden.indexOf(str) < 0) {
        return str;
    }
}).forEach(function(letter) { console.log(letter);});

I guess more directly:

for(var i=0 ; i < str.length ; i++) {
    if(forbidden.indexOf(str) < 0) {
        console.log(str[i]);
    }
}

But there’s no built in way to filter in your for loop.

Answered By: ChadF

Reading the code, I assume forbidden can have more than 1 character. I’m also assuming the output should be “12345”

var string = "12=34-5";

var forbidden = "=-";

console.log(string.split("").filter(function(str){
    return forbidden.indexOf(str) < 0;
}).join(""))

If the output is “1” “2” “3” “4” “5” on separate lines

var string = "12=34-5";

var forbidden = "=-";

string.split("").forEach(function(str){
    if (forbidden.indexOf(str) < 0) {
        console.log(str);
    }
});
Answered By: Jaromanda X

Update: Array comprehensions were removed from the standard. Quoting MDN:

The array comprehensions syntax is non-standard and removed starting with Firefox 58. For future-facing usages, consider using Array.prototype.map, Array.prototype.filter, arrow functions, and spread syntax.

See this answer for an example with Array.prototype.map:

let emails = people.map(({ email }) => email);

Original answer:

Yes, JavaScript will support array comprehensions in the upcoming EcmaScript version 7.

Here’s an example.

var str =  "1234-5";
var ignore = "-";

console.log([for (i of str) if (!ignore.includes(i)) i]);
Answered By: DRD

For “completeness”-sake, here’s a shorter regexp version.

var str =  "1234-5";
var ignore = "-=";

console.log(str.replace(new RegExp(ignore.split("").join("|")), "").split(""));

EDIT: To make sure that RegExp does not “choke” on special characters, ignore can be implemented as regexp literal, instead of a string:

var str =  "1234-5";
var ignore = /[+=-]/;
console.log(str.replace(ignore, "").split(""));
Answered By: DRD

It does have a poor mans version

const string = '1234-5'

const forbidden = '-'

print([int(i) for i in str(string) if i not in forbidden])
const result = string.split('').filter(char => char !== forbidden);
console.log(result)

In JS you can only iterate over single elements in array, so no extraction of multiple entries at a time like in Python.

For this particular case you should use a RegExp to filter the string though.

Answered By: Henrik Vendelbo

You could easily achieve this behavior using an application functor.

Array.prototype.ap = function(xs) {
  return this.reduce((acc, f) => acc.concat(xs.map(f)), []) 
}


const result = [x => x +1].ap([2])
console.log(result)
Answered By: martin

Given the question’s Python code

print([int(i) for i in str(string) if i not in forbidden])

this is the most direct translation to JavaScript (ES2015):

const string = '1234-5';
const forbidden = '-';

console.log([...string].filter(c => !forbidden.includes(c)).map(c => parseInt(c)));
// result: [ 1, 2, 3, 4, 5 ]

Here is a comparison of the Python and JavaScript code elements being used:
(Python -> Javascript):

  • print -> console.log
  • unpacking string to list -> spread operator
  • list comprehension ‘if’ -> Array.filter
  • list comprehension ‘for’ -> Array.map
  • substr in str? -> string.includes
Answered By: Colin D Bennett

JavaScript no longer supports array comprehensions.

I too was looking for the JavaScript equivalent. Mozilla Developer’s Network indicates that this functionality is no longer supported.
The preferred syntax is referenced in the aforementioned link.

Answered By: VanBantam

You could have a look at CoffeeScript.
CoffeeScript adds missing features to java-script and allows you to write cleaner, more readable code. https://coffeescript.org/#coffeescript-2

You write a .coffee file and the coffeScript-compiler compiles your coffee file into a JavaScript file. Because the translation into JavaScript happens by compiling, the script should not run any slower.

So your code would look like the following in coffee script:

string = '1234-5'

forbidden = '-'

alert(JSON.stringify(+i for i in string when i isnt forbidden))

Honestly, this is even easier to read then the python counterpart. And it compiles quickly to the fallowing JavaScript:

var forbidden, i, string;

string = '1234-5';

forbidden = '-';

alert(JSON.stringify((function() {
  var j, len, results;
  results = [];
  for (j = 0, len = string.length; j < len; j++) {
    i = string[j];
    if (i !== forbidden) {
      results.push(+i);
    }
  }
  return results;
})()));

You don’t even need to install anything. On their website you can play around with it, and it will show you the translated JavaScript code.

Answered By: Dario Viva

Javascript doesn’t need list comprehensions because the map and filter functions work better in the language compared to Python.

In Python:

[int(i) for i in '1234-5' if i != '-'] 
# is equivalent to the ugly
list(map(lambda _: int(_),filter(lambda _: _!='-','1234-5')))
# so we use list comprehensions

In Javascript, to me this is fine once you’re familiar with the syntax:

[...'1234-5'].filter(_=> _!='-').map(_=> parseInt(_))
Answered By: Riaz Rizvi
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.