Home > Blockchain >  Extract nodeList item ids as an array with array map
Extract nodeList item ids as an array with array map

Time:12-11

I want to save a set of ids based on a nodeList returned by a querySelector.

I achieved it with a very procedural approach, thinking in terms of steps.

  1. Select items
  2. Create an array
  3. Iterate over items
  4. Get the id
  5. Push it into the array

const getThem = document.querySelectorAll('.get-me');

let arrayOfData = [];

Array.prototype.forEach.call (getThem, function (node){
    arrayOfData.push(node.id);
});

console.log(arrayOfData);
<ul>
<li  id="one">One</li>
<li  id="two">Two</li>
<li  id="three">Three</li>
</ul>

I wonder if I can get this done with array map, to reduce the amount of lines and also take advantage of modern Javascript features.

I tried with:

const getThem = document.querySelectorAll('.get-me');
Array.prototype.map.call(getThem, (item) => ({ [id]: item.id }));
console.log(getThem);

But it doesn't work.

CodePudding user response:

Unfortunately, the NodeList that is returned by .querySelectorAll() doesn't have a .map() method. However, as it is iterable, you can pass it to Array.from(), and use the second mapping argument to perform your mapping:

const getThem = document.querySelectorAll('.get-me');
const arrayOfData = Array.from(getThem, node => node.id);
console.log(arrayOfData);
<ul>
  <li  id="one">One</li>
  <li  id="two">Two</li>
  <li  id="three">Three</li>
</ul>

This does two things in one go, it converts your NodeList to an array, and it performs the mapping based on the second argument. This is opposed to doing something like Array.from(getThem).map(...) and [...getThem].map(...) which both do two iterations over your items.


I tried with:

const getThem =
document.querySelectorAll('.get-me');
Array.prototype.map.call(getThem, (item) => ({ [id]: item.id }));
console.log(getThem); 

But it doesn't work.

This does also work, you just need to store the return value in a variable a log that. .map() doesn't change the original array, it returns a new one instead:

const getThem = document.querySelectorAll('.get-me');
const res = Array.prototype.map.call(getThem, (item) => item.id);
console.log(res);
<ul>
  <li  id="one">One</li>
  <li  id="two">Two</li>
  <li  id="three">Three</li>
</ul>

CodePudding user response:

Another way to do it using spread operator and array map like below

const getThem = document.querySelectorAll('.get-me');
const nodes = [...getThem];

const arrayOfData = nodes.map(node => node.id);

console.log(arrayOfData);
<ul>
  <li  id="one">One</li>
  <li  id="two">Two</li>
  <li  id="three">Three</li>
</ul>

CodePudding user response:

You can do:

const elems = document.querySelectorAll('.get-me')
const arrayOfData = Array.from(elems).map(({ id }) => id)

console.log(arrayOfData)
<ul>
  <li  id="one">One</li>
  <li  id="two">Two</li>
  <li  id="three">Three</li>
</ul>

  • Related