Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Make Javascript do List Comprehension

What is the cleanest way to make Javascript do something like Python's list comprehension?

In Python if I have a list of objects whose name's I want to 'pull out' I would do this...

list_of_names = [x.name for x in list_of_objects] 

In javascript I don't really see a more 'beautiful' way of doing that other than just using a for loop construct.

FYI: I'm using jQuery; maybe it has some nifty feature that makes this possible?

More specifically, say I use a jQuery selector like $('input') to get all input elements, how would I most cleanly create an array of all the name attributes for each of these input elements--i.e., all of the $('input').attr('name') strings in an array?

like image 889
Chris W. Avatar asked Feb 11 '11 00:02

Chris W.


People also ask

How do I make a list comprehension in JavaScript?

An easy way to replicate Python's list comprehension is to use the Array. filter() method available in JavaScript. The Array. filter() method allows you to create a new array out of an existing array by applying a certain filter to it.

Does JavaScript support list comprehension?

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

Does typescript have list comprehension?

List comprehension is a method from mathematics to describe a collection of values in a very compact and elegant way.

Are list comprehensions faster than map?

Map function is faster than list comprehension when the formula is already defined as a function earlier. So, that map function is used without lambda expression.


2 Answers

generic case using Array.map, requires javascript 1.6 (that means, works on every browser but IE < 9) or with an object augmenting framework like MooTools works on every browser:

var list_of_names = document.getElementsByTagName('input').map(   function(element) { return element.getAttribute('name'); } ); 

If dealing with an iterable that doesn't provide map (such as generators), spread syntax can be used to first create an array:

[...Array(10).keys()].map(x => x * 2 + 3) 

Spread syntax will also work with arrays, so if you need to apply map to any iterable, it's safest to first spread it into a list.

(Note this example also uses an arrow function, which requires ES6 support. Most browser versions support both or neither. IE supports neither, if it itself needs to be supported, though IE has been replaced by Edge for awhile.)

jQuery specific example, works on every browser:

var list_of_names = jQuery.map(jQuery('input'), function(element) { return jQuery(element).attr('name'); }); 

the other answers using .each are wrong; not the code itself, but the implementations are sub-optimal.

Edit: there's also Array comprehensions introduced in Javascript 1.7, but this is purely dependant on syntax and cannot be emulated on browsers that lack it natively. This is the closest thing you can get in Javascript to the Python snippet you posted. However that got removed from the language

like image 140
gonchuki Avatar answered Sep 30 '22 00:09

gonchuki


A list comprehension has a few parts to it.

  1. Selecting a set of something
  2. From a set of Something
  3. Filtered by Something

In JavaScript, as of ES5 (so I think that's supported in IE9+, Chrome and FF) you can use the map and filter functions on an array.

You can do this with map and filter:

var list = [1,2,3,4,5].filter(function(x){ return x < 4; })                .map(function(x) { return 'foo ' + x; });  console.log(list); //["foo 1", "foo 2", "foo 3"] 

That's about as good as it's going to get without setting up additional methods or using another framework.

As for the specific question...

With jQuery:

$('input').map(function(i, x) { return x.name; }); 

Without jQuery:

var inputs = [].slice.call(document.getElementsByTagName('input'), 0),     names = inputs.map(function(x) { return x.name; }); 

[].slice.call() is just to convert the NodeList to an Array.

like image 41
Ben Lesh Avatar answered Sep 29 '22 23:09

Ben Lesh