A K
A K

Reputation: 1674

Does JavaScript support array/list comprehensions like Python?

I'm trying to get an array from each individual integer from the string. In Python, I would do:

string = '1234-5'
forbidden = '-'

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

Does JavaScript have something similar?

Upvotes: 138

Views: 154919

Answers (11)

Bernardo Dal Corno
Bernardo Dal Corno

Reputation: 2088

A bit late for the party, but as of 2024 I would do:

console.log(parseInt(string.split('').filter(i => !forbidden.includes(i))))

Upvotes: 1

Rian Rizvi
Rian Rizvi

Reputation: 10845

JavaScript doesn't need list comprehensions because map and filter 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')))

Whereas in JavaScript, map and filter are Array methods, so:

[...'1234-5'].filter(_=> _!='-').map(_=> parseInt(_))

Upvotes: 3

Colin D Bennett
Colin D Bennett

Reputation: 12140

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

Upvotes: 28

Dario Viva
Dario Viva

Reputation: 267

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.

Upvotes: 1

DRD
DRD

Reputation: 5813

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]);

Upvotes: 98

VanBantam
VanBantam

Reputation: 788

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.

Upvotes: 4

martin
martin

Reputation: 49

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)

Upvotes: 4

Henrik Vendelbo
Henrik Vendelbo

Reputation: 11

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.

Upvotes: 0

DRD
DRD

Reputation: 5813

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(""));

Upvotes: 2

ChadF
ChadF

Reputation: 1758

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.

Upvotes: 5

Jaromanda X
Jaromanda X

Reputation: 1

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);
    }
});

Upvotes: 10

Related Questions