Make Javascript do List Comprehension

后端 未结 10 1146
情话喂你
情话喂你 2020-12-05 09:05

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 \'

相关标签:
10条回答
  • 2020-12-05 09:44

    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.

    0 讨论(0)
  • 2020-12-05 09:44

    Those interested in "beautiful" Javascript should probably check out CoffeeScript, a language which compiles to Javascript. It essentially exists because Javascript is missing things like list comprehension.

    In particular, Coffeescript's list comprehension is even more flexible than Python's. See the list comprehension docs here.

    For instance this code would result in an array of name attributes of input elements.

    [$(inp).attr('name') for inp in $('input')]
    

    A potential downside however is the resulting Javascript is verbose (and IMHO confusing):

    var inp;
    [
      (function() {
        var _i, _len, _ref, _results;
        _ref = $('input');
        _results = [];
        for (_i = 0, _len = _ref.length; _i < _len; _i++) {
          inp = _ref[_i];
          _results.push($(inp).attr('name'));
        }
        return _results;
      })()
    ];
    
    0 讨论(0)
  • 2020-12-05 09:47

    Using jQuery .each() function, you can loop through each element, get the index of the current element and using that index, you can add the name attribute to the list_of_names array...

    var list_of_names = new Array();
    
    $('input').each(function(index){
      list_of_names[index] = $(this).attr('name');
    });
    

    While this is essentially a looping method, which you specified you did not want, it is an incredibly neat implementation of looping and allows you to run the loop on specific selectors.

    Hope that helps :)

    0 讨论(0)
  • 2020-12-05 09:49

    So, python's list comprehensions actually do two things at once: mapping and filtering. For example:

    list_of_names = [x.name for x in list_of_object if x.enabled]
    

    If you just want the mapping part, as your example shows, you can use jQuery's map feature. If you also need filtering you can use jQuery's "grep" feature.

    0 讨论(0)
  • 2020-12-05 09:50

    Do this in 2020

    const names = collection.map(x => x.name);
    

    MDN | Array.prototype.map()

    Old Answer from 2012

    Yeah—I miss list comprehensions too.

    Here's an answer that's slightly less verbose than @gonchuki's answer and converts it into an actual array, instead of an object type.

    var list_of_names = $('input').map(function() {
        return $(this).attr('name');
    }).toArray();
    

    A use case of this is taking all checked checkboxes and joining them into the hash of the URL, like so:

    window.location.hash = $('input:checked').map(function() {
        return $(this).attr('id');
    }).toArray().join(',');
    
    0 讨论(0)
  • 2020-12-05 09:57

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

    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

    0 讨论(0)
提交回复
热议问题