139

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?

2
  • No it does not. Although JavaScript does support higher-ordered functions and ES5 adds support for some basic map/filter support in Array.prototype (there is no direct flatmap, although that can be emulated map-concat). There are additional libraries like underscore which add to this set of 'primitives' that is all Python is doing under the list-comprehension syntax guise. Commented Jul 11, 2015 at 4:14
  • See stackoverflow.com/questions/33872615/… Commented Nov 17, 2016 at 2:15

11 Answers 11

99

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]);
Sign up to request clarification or add additional context in comments.

6 Comments

I believe the OP was asking about JavaScript code that they can actually run today, not at some indefinite time in the future.
Babel is great! Maybe you could expand your answer a bit and give an example of what the syntax would be, and how you can use Babel to use it in today's browsers.
The MDN page developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… says at the top: "The array comprehensions is non-standard, and it's unlikely to be added to ECMAScript". stackoverflow.com/questions/33872615/… seems to have more details
In case anyone else stumbles over this answer many years later, this does NOT work as proven by the "example" provided in the link above.
It's very sad that list comprehensions were never added to the language. They're very nice to use and easy to read. Although, it's never too much effort to not use them.
|
28

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

Comments

10

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

Comments

5

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.

Comments

4

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)

4 Comments

Did you mean applicative functor? Can you give more context to your answer? It's quite intriguing.
while it seems interesting at a first sight, I cannot see any reason to use this instead of a plain [2].map( x => x+1)
My guess would be that it mimics the feel of the python equivalent
Compared to a pythonic list comprehension, this is quite ugly.
4

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.

Comments

3

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(_))

1 Comment

It is so frikking helpful to get this multilingual example. A Rosetta Stone of comprehensions, as it were. I am slightly less daunted by .filter() and .map() now.
2

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

2 Comments

var ignore = "-+=";
Dang, I really like your solution as well; it falls more in my type of coding
1

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.

Comments

1

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

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

Comments

0

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.

1 Comment

Please put the javascript and python code in two seperate code blocks.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.