1

I need to get an array of all element ID's of elements of a given class (e.g. "main-menu-item"). This is what I have so far:

Array.prototype.map.call(document.querySelectorAll(".main-menu-item"), (elem => elem.id));

Is there a cleaner and/or more concise way to do this?

Keith Bennett
  • 4,722
  • 1
  • 25
  • 35

2 Answers2

5

Use the spread operator:

[...document.querySelectorAll(".main-menu-item")].map(elem => elem.id)
Daniel Rodríguez Meza
  • 1,167
  • 1
  • 8
  • 17
3

You can use Array.from() with the mapping function, allowing you to convert the NodeList into an array while also specifying how each element should be transformed:

const res = Array.from(document.querySelectorAll(".main-menu-item"), ({id}) => id);
console.log(res);
<p class="main-menu-item" id="1">one</p>
<p class="main-menu-item" id="2">two</p>
<p class="main-menu-item" id="3">three</p>
Nick Parsons
  • 45,728
  • 6
  • 46
  • 64
  • I ran this alongside Daniel Rodriguez Meza's solution on jsbench.me and this one turned out fastest more often than not. But both solutions are extremely close and it all comes to which syntax you are more accustomed to. – Artur Jul 07 '20 at 02:21
  • 1
    Ah, interesting. I guess the spread then map option presented in Daniel's code does two loops in total of the array contents, one for spreading the content into the array, and the other for mapping, so a total of 2N operations, whereas this does the converting to an array and mapping in the one loop, so its just N operations. At the end of the day, they're both linear-time O(N), so performance is not really going to be a big difference between the two pieces of code when the number of elements becomes large. – Nick Parsons Jul 07 '20 at 02:23
  • 1
    While both answers were correct and helpful, I decided I liked Daniel's answer the best (even though it might be slightly slower) because it was more obvious to me what it was doing. Thanks to both of you! – Keith Bennett Jul 07 '20 at 06:11