vdegenne
vdegenne

Reputation: 13288

How to concatenate an HTMLCollection with an array?

It may sounds like a silly question but

var arr1 = ['1', '2'];
var arr2 = ['3', '4'];
console.log(arr1.concat(arr2));

will output ["1", "2", "3", "4"]

But

var arr1 = ['1', '2'];
console.log(
  arr1.concat(document.getElementsByTagName('h1'))
);

will output ["1", "2", HTMLCollection[2]]

How do I concatenate the html collection with an array ?

Upvotes: 7

Views: 8053

Answers (3)

RobG
RobG

Reputation: 147453

You can use Array.from, however it's fairly new so may not be supported by all the browsers you need. Some alternatives, the last of which will be supported by all browsers in use:

  1. Spread syntax, which is new, only supported by the most recent browsers and no version of IE
  2. Array.prototype.slice.call to convert the NodeList to an array, but will fail in IE 8 where passing host objects to built–in methods as this fails
  3. Array.prototype.map.call to convert to an array. Avoids the IE 8 issue as map will need to be polyfilled (but then you might as well use a polyfill for Array.from and be done with it)
  4. Use array.concat.apply and pass the NodeList as an argument, no need for polyfills for old browsers

Runnable snippet below.

var arr = [0,1];
var divs = document.querySelectorAll('div');

// Use spread syntax, pretty new though
var spread = arr.concat(...divs);
console.log('Spread\n' + spread.join('\n'));

// Convert to array using slice, then concat
var sliced = Array.prototype.slice.call(divs).concat(arr);
console.log('Sliced\n' + sliced.join('\n'));

// Convert to array using map, then concat
var mapped = Array.prototype.map.call(divs, function(div){return div}).concat(arr);
console.log('Mapped\n' + mapped.join('\n'));

// Call concat with apply directly using concat
var conned = arr.concat.apply(arr, divs);
console.log('Conned\n' + conned.join('\n'));
<div>div1</div>
<div>div2</div>

Upvotes: 1

T.J. Crowder
T.J. Crowder

Reputation: 1074969

You can use push.apply, like so:

var arr1 = ['1', '2'];
arr1.push.apply(arr1, document.getElementsByTagName('h1'));
console.log(arr1);
<h1>x</h1>
<h1>y</h1>

And in ES2015+ (aka ES6+), you can use push with spread notation:

var arr1 = ['1', '2'];
arr1.push(...document.getElementsByTagName('h1'));
console.log(arr1);
<h1>x</h1>
<h1>y</h1>

Note that in both cases, this is different from concat in that it avoids creating a new array (it just modifies the original one referenced by arr1). Whether that difference is a good thing (not creating unnecessary objects) or a bad thing (I wanted a new array!) depends on your use case. :-)

Upvotes: 1

lonesomeday
lonesomeday

Reputation: 237975

You need to convert the HTMLCollection into an array. The best way of doing this in modern Javascript is Array.from. This converts any array-like object (or other iterable value) into a real Javascript array.

arr1.concat(Array.from(document.getElementsByTagName('h1')))

Upvotes: 10

Related Questions