I want to select all elements with class name find-me
and group them in separate arrays (or NodeLists) based on their other classes, if idential. Here is an example:
<div class="find-me one two">
Element 1
</div>
<div class="find-me one two">
Element 2
</div>
<div class="find-me one two three">
Element 3
</div>
<div class="find-me one two three">
Element 4
</div>
<div class="find-me one two four">
Element 5
</div>
<div class="find-me one two">
Element 6
</div>
<div class="one two">
Element 7
</div>
My goal is to have:
find-me, one, two
)find-me, one, two, three
)find-me, one, two, four
)find-me
classI suppose I have to use document.querySelectorAll('.find-me')
to first get a NodeList of all the elements I am interested in.
But then? I was thinking I could compare the list of classes from the current element with the previous one but how can I keep track of what element goes to what group? Any idea how to achieve that?
Sounds like a good opportunity to use Object.groupBy
, but be aware of its poor coverage
const groups = Object.groupBy(document.querySelectorAll('.find-me'), e => e.classList);
console.log(groups);
<div class="find-me one two">
Element 1
</div>
<div class="find-me one two">
Element 2
</div>
<div class="find-me one two three">
Element 3
</div>
<div class="find-me one two three">
Element 4
</div>
<div class="find-me one two four">
Element 5
</div>
<div class="find-me one two">
Element 6
</div>
<div class="one two">
Element 7
</div>
Using the same concept, you can write a reduce function to achieve the same goal, also the order/repetitive classes doesn't matter:
const groups = [...document.querySelectorAll('.find-me')].reduce((acc, cur) => {
const key = [...cur.classList].sort();
acc[key] ??= [];
// use the following code instead of the line above if you need to support IE11
// acc[key] || (acc[key] = []);
acc[key].push(cur);
return acc;
}, {});
console.log(groups);
<div class="find-me one two">
Element 1
</div>
<div class="two find-me one one">
Element 2
</div>
<div class="find-me one two three">
Element 3
</div>
<div class="find-me one three two ">
Element 4
</div>
<div class="find-me one two four">
Element 5
</div>
<div class="find-me one two">
Element 6
</div>
<div class="one two">
Element 7
</div>