Сделать Javascript выполнимым списком

Каков самый чистый способ заставить Javascript сделать что-то вроде понимания списка Python?

В Python, если у меня есть список объектов, чье имя я хочу «вытащить», я бы сделал это …

list_of_names = [x.name for x in list_of_objects] 

В javascript я действительно не вижу более «красивого» способа сделать это иначе, чем просто использовать конструкцию for loop.

FYI: Я использую jQuery; возможно, у него есть отличная функция, которая делает это возможным?

Более конкретно, скажем, я использую селектор jQuery, такой как $('input') чтобы получить все input элементы, как бы я наиболее четко создал массив всех атрибутов name для каждого из этих input элементов – то есть всех $('input').attr('name') строки в массиве?

10 Solutions collect form web for “Сделать Javascript выполнимым списком”

в общем случае с использованием Array.map требуется javascript 1.6 (это означает, что он работает в каждом браузере, но IE <9) или с расширенной инфраструктурой объекта, такой как MooTools, работает в каждом браузере:

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

Пример jQuery, работает в каждом браузере:

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

другие ответы с использованием .each неверны; а не сам код, но реализации субоптимальные.

Изменить: в Javascript 1.7 реализованы также функции Array , но это зависит исключительно от синтаксиса и не может быть эмулировано в браузерах, которые не имеют его изначально. Это самая близкая вещь, которую вы можете получить в Javascript в фрагменте Python, который вы опубликовали.

У составления списка есть несколько частей.

  1. Выбор набора чего-то
  2. Из набора чего-то
  3. Отфильтровано Something

В JavaScript, как и в ES5 (поэтому я думаю, что это поддерживается в IE9 +, Chrome и FF), вы можете использовать функции map и 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"] 

Это примерно так же хорошо, как и без дополнительных методов или с использованием другой структуры.

Что касается конкретного вопроса …

С помощью jQuery:

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

Без jQuery:

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

[].slice.call() – это просто преобразовать NodeList в Array .

Те, кто интересуется «красивым» Javascript, должны, вероятно, проверить CoffeeScript , язык, который компилируется в Javascript. Это по существу существует, потому что Javascript не хватает таких вещей, как понимание списков.

В частности, понимание списка Coffeescript является еще более гибким, чем Python. См. Здесь документы по пониманию списка .

Например, этот код приведет к массиву атрибутов имени input элементов.

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

Потенциальный недостаток, однако, является результатом Javascript многословным (и IMHO запутанным):

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

Таким образом, понимание списков python фактически делает сразу две вещи: сопоставление и фильтрацию. Например:

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

Если вам просто нужна часть отображения, как показывает ваш пример, вы можете использовать функцию карты jQuery. Если вам также нужна фильтрация, вы можете использовать функцию «grep» jQuery.

Повторяемый способ сделать это – создать крошечный плагин jQuery следующим образом:

 jQuery.fn.getArrayOfNames = function() { var arr = []; this.each( function() { arr.push(this.name || ''); } ); return arr; }; 

Тогда вы можете использовать его так:

 var list_of_names = $('input').getArrayOfNames(); 

Это не понимание списков, но это не существует в javascript. Все, что вы можете сделать, это использовать javascript и jquery для того, для чего это хорошо.

Да, я тоже скучаю по спискам.

Вот ответ, который немного менее подробен, чем ответ @ gonchuki и преобразует его в фактический массив, а не тип объекта.

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

В этом случае все флажки отмечены и присоединяются к хэшу URL-адреса, например:

 window.location.hash = $('input:checked').map(function() { return $(this).attr('id'); }).toArray().join(','); 

Существует однострочный подход, он предполагает использование вложенной функции закрытия в конструкторе списка. И функция, которая длится с ней, чтобы сгенерировать последовательность. Его определение ниже:

 var __ = generate = function(initial, max, list, comparision) { if (comparision(initial)) list.push(initial); return (initial += 1) == max + 1 ? list : __(initial, max, list, comparision); }; [(function(l){ return l; })(__(0, 30, [], function(x) { return x > 10; }))]; // returns Array[20] var val = 16; [(function(l){ return l; })(__(0, 30, [], function(x) { return x % val == 4; }))]; // returns Array[2] 

Это реализация на основе диапазона, такая как диапазон Python (мин., Макс.). Кроме того, эта процедура выглядит следующим образом:

 [{closure function}({generator function})]; 

некоторые тесты:

 var alist = [(function(l){ return l; })(__(0, 30, [], function(x) { return x > 10; }))]; var alist2 = [(function(l){ return l; })(__(0, 1000, [], function(x) { return x > 10; }))]; // returns Array[990] var alist3 = [(function(l){ return l; })(__(40, 1000, [], function(x) { return x > 10; }))]; var threshold = 30*2; var alist3 = [(function(l){ return l; })(__(0, 65, [], function(x) { return x > threshold; }))]; // returns Array[5] 

Хотя это решение не является самым чистым, он выполняет свою работу. И в производстве я бы, вероятно, советовал ему.

Наконец, можно выбрать не использовать рекурсию для моего метода генерации, поскольку это ускорит работу. Или даже лучше использовать встроенную функцию из множества популярных Javascript-библиотек. Вот перегруженная реализация, которая также будет учитывать свойства объекта

 // A list generator overload implementation for // objects and ranges based on the arity of the function. // For example [(function(l){ return l; })(__(0, 30, [], function(x) { return x > 10; }))] // will use the first implementation, while // [(function(l){ return l; })(__(objects, 'name', [], function(x, y) { var x = x || {}; return x[y] }))]; // will use the second. var __ = generator = function(options) { return arguments.length == 4 ? // A range based implemention, modeled after pythons range(0, 100) (function (initial, max, list, comparision) { var initial = arguments[0], max = arguments[1], list = arguments[2], comparision = arguments[3]; if (comparision(initial)) list.push(initial); return (initial += 1) == max + 1 ? list : __(initial, max, list, comparision); })(arguments[0], arguments[1], arguments[2], arguments[3]): // An object based based implementation. (function (object, key, list, check, acc) { var object = arguments[0], key = arguments[1], list = arguments[2], check = arguments[3], acc = arguments[4]; acc = acc || 0; if (check(object[acc], key)) list.push(object[acc][key]); return (acc += 1) == list.length + 1 ? list : __(object, key, list, check, acc); })(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4]); }; 

Применение:

 var threshold = 10; [(function(l){ return l; })(__(0, 65, [], function(x) { return x > threshold; }))]; // returns Array[5] -> 60, 61, 62, 63, 64, 65 var objects = [{'name': 'joe'}, {'name': 'jack'}]; [(function(l){ return l; })(__(objects, 'name', [], function(x, y) { var x = x || {}; return x[y] }))]; // returns Array[1] -> ['Joe', 'Jack'] [(function(l){ return l; })(__(0, 300, [], function(x) { return x > 10; }))]; 

Синтаксис сосет, я знаю!

Удачи.

Массивные представления являются частью проекта ECMAScript 6. В настоящее время (январь 2014 года) реализуется только JavaScript Mozilla / Firefox.

 var numbers = [1,2,3,4]; var squares = [i*i for (i of numbers)]; // => [1,4,9,16] var somesquares = [i*i for (i of numbers) if (i > 2)]; // => [9,16] 

Хотя недавно ECMAScript 6 переключился на синтаксис слева направо, похожий на C # и F #:

 var squares = [for (i of numbers) i*i]; // => [1,4,9,16] 

http://kangax.github.io/es5-compat-table/es6/#Array_comprehensions

Это пример того, где Coffeescript действительно сияет

 pows = [x**2 for x in foo_arr] list_of_names = [x.name for x in list_of_objects] 

Эквивалентным Javascript будет:

 var list_of_names, pows, x; pows = [ (function() { var _i, _len, _results; _results = []; for (_i = 0, _len = foo_arr.length; _i < _len; _i++) { x = foo_arr[_i]; _results.push(Math.pow(x, 2)); } return _results; })() ]; list_of_names = [ (function() { var _i, _len, _results; _results = []; for (_i = 0, _len = list_of_objects.length; _i < _len; _i++) { x = list_of_objects[_i]; _results.push(x.name); } return _results; })() ]; 

Используя .each() jQuery .each() , вы можете .each() каждый элемент, получать индекс текущего элемента и использовать этот индекс, вы можете добавить атрибут list_of_names массив list_of_names

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

Хотя это, по сути, метод цикла, который вы указали не хотите, это невероятно реалистичная реализация цикла и позволяет вам запускать цикл для определенных селекторов.

Надеюсь, это поможет 🙂

  • Python (List Comprehension): возврат двух (или более) элементов для каждого элемента
  • Как подойти к связанному списку, используя понимание списка?
  • Как получить список индексов ненулевых элементов в списке?
  • Понимание списков в Haskell, Python и Ruby
  • Отображение вложенного списка с помощью List Comprehension в Python?
  • Являются ли перечисления синтаксического сахара для `list (generator expression)` в Python 3?
  • Понимание этой строки: list_of_tuples =
  • Анафорическое понимание списка в Python
  • замена цикла while со списком
  • Python: Как установить локальную переменную в понимании списка?
  • Странное поведение лямбды в понимании списка
  •  
    Interesting Posts for Van-Lav

    Хруст json с python

    У списков Python есть эквивалент dict.get?

    При получении объекта Document из объекта Word.Application его члены не заполняются из кеша gencache, в то время как VBSEdit может их получить

    Как преобразовать .tsv в .csv?

    Как использовать контекстные менеджеры для переменных экземпляра

    Автоматическое преобразование типов пользовательских классов

    Алгоритм для четких отступов SQL-операторов (реализация Python была бы приятной)

    Какой модуль или класс пути используют люди Python вместо os.path?

    Как проверить, установлен ли аргумент из командной строки?

    Как получить имя пользователя Windows для посетителя страницы с помощью Flask?

    Удалите пробелы из теплового экрана matplotlib

    как интерпретировать эту ошибку "UnicodeDecodeError: кодек ascii не может декодировать байт 0xe2 в позиции 164: порядковый номер не в диапазоне (128)"

    Gremlin Python Gizmo, как запросить в графе db

    Какая магия python выполняет dir () с __getattr__?

    Как извлечь видео ID из ссылки YouTube в Python?

    Python - лучший язык программирования в мире.