6

Наиболее эффективный способ преобразовать HTMLCollection в массив

3

Как более эффективно преобразовать HTMLCollection в массив, нежели итерировать по содержимому коллекции и вручную добавлять каждый элемент в массив?

5 ответ(ов)

1

Не уверены, что это самый эффективный способ, но краткий синтаксис ES6 может выглядеть так:

let arry = [...htmlCollection]

Дополнение: Еще один вариант из комментария Chris_F:

let arry = Array.from(htmlCollection)
0

Я увидел более лаконичный способ получить методы Array.prototype, который также работает хорошо. Преобразование объекта HTMLCollection в объект Array демонстрируется ниже:

[].slice.call(yourHTMLCollectionObject);

И, как упоминалось в комментариях, для старых браузеров, таких как IE7 и более ранние версии, вам просто нужно использовать функцию совместимости, например:

function toArray(x) {
    for (var i = 0, a = []; i < x.length; i++)
        a.push(x[i]);

    return a;
}

Я знаю, что это старый вопрос, но мне показалось, что принятый ответ немного неполный; поэтому я решил поделиться этим способом, если кому-то это будет полезно.

0

Этот код работает во всех браузерах, включая более ранние версии Internet Explorer:

var arr = [];
[].push.apply(arr, htmlCollection);

Поскольку jsperf в данный момент недоступен, вот ссылка на jsfiddle, в котором сравнивается производительность различных методов: https://jsfiddle.net/qw9qf48j/

0

Я предполагаю, что вызов функций Array.prototype на экземплярах HTMLCollection является гораздо более эффективным вариантом, чем преобразование коллекций в массивы (например, с помощью [...collection] или Array.from(collection)), поскольку в последнем случае коллекция неявно итерируется, и создается новый объект массива, что потребляет дополнительные ресурсы. Функции итерации Array.prototype можно безопасно вызывать для объектов с последовательными числовыми ключами, начиная с [0], и с свойством length, имеющим корректное числовое значение, равное количеству таких ключей (включая, например, экземпляры HTMLCollection и FileList), так что это надежный способ. Также, если подобные операции требуется выполнять часто, можно использовать пустой массив [] для быстрого доступа к функциям Array.prototype. Вот работающий пример:

alert(
    Array.prototype.reduce.call(
        document.querySelector('ol').children,
        (acc, { textContent }, i) => `${acc}${i + 1}) ${textContent}` + `\n`,
        '',
    ),
);
<ol>
    <li>foo</li>
    <li>bar</li>
    <li>bat</li>
    <li>baz</li>
</ol>
0

Это мое личное решение, основанное на информации из этой темы:

var Divs = new Array();    
var Elemns = document.getElementsByClassName("divisao");
try {
    Divs = Elemns.prototype.slice.call(Elemns);
} catch(e) {
    Divs = $A(Elemns);
}

Где функция $A была описана Гартом Дэвисом в его посте:

function $A(iterable) {
  if (!iterable) return [];
  if ('toArray' in Object(iterable)) return iterable.toArray();
  var length = iterable.length || 0, results = new Array(length);
  while (length--) results[length] = iterable[length];
  return results;
}

В этом коде я сначала пытаюсь использовать метод slice для преобразования коллекции Elemns, полученной с помощью getElementsByClassName, в массив. Если это не удается — что может произойти в старых браузерах — в качестве резервного варианта использую функцию $A, которая также может обрабатывать коллекции, поддерживающие длину. Таким образом, мы обеспечиваем кроссбраузерную совместимость.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь