-2

I need to match any item within 2 array's and then return the value of that match. For example:

let arr1 = [ 'grid-view' ,'list-view' ];
let arr2 = [ 'test', 'list-view' ];

From the above I would get list-view returned.

This is what I have at the moment, however it returns true, whereas I need the actual match. Trying avoid doing horrid big loops and having too much code.

let switches = document.querySelectorAll('[data-switch]');
let switchesClasses = [].slice.call(switches).map(x => x.dataset.switchClass);

const found = Array.from(document.querySelector('.test').classList).some(r => switchesClasses.includes(r));

console.log(found);
<div class="showroom-layout-toggle" data-switch-group="showroom_layout" data-switch-target=".test" data-switch-cookie>
  <button class="grid-toggle" data-switch data-switch-class="grid-view">Grid</button>
  <button class="grid-toggle" data-switch data-switch-class="list-view">List</button>
</div>

<div class="test list-view">Hello</div>
Martyn Ball
  • 4,679
  • 8
  • 56
  • 126

3 Answers3

1

Array.prototype.some()

The some() method tests whether at least one element in the array passes the test implemented by the provided function. It returns a Boolean value.

Instead of some() try with Array.prototype.filter():

The filter() method creates a new array with all elements that pass the test implemented by the provided function.

let arr1 = [ 'grid-view' ,'list-view' ];
let arr2 = [ 'test', 'list-view' ];

let switches = document.querySelectorAll('[data-switch]');
let switchesClasses = [].slice.call(switches).map(x => x.dataset.switchClass);

const found = Array.from(document.querySelector('.test').classList).filter(r => switchesClasses.includes(r));
console.log(found);
<div class="showroom-layout-toggle" data-switch-group="showroom_layout" data-switch-target=".test" data-switch-cookie>
  <button class="grid-toggle" data-switch data-switch-class="grid-view">Grid</button>
  <button class="grid-toggle" data-switch data-switch-class="list-view">List</button>
</div>

<div class="test list-view">Hello</div>
Mamun
  • 66,969
  • 9
  • 47
  • 59
1

If you replace "some" with "filter", you'll get an array of the matched classes.

So, with your test arrays, that would look like this:

let found = arr2.filter(r => arr1.includes(r));
console.log(found); // ["list-view"]
0

Use .find instead of .some:

let switches = document.querySelectorAll('[data-switch]');
let switchesClasses = [].slice.call(switches).map(x => x.dataset.switchClass);

const found = Array.from(document.querySelector('.test').classList)
  .find(r => switchesClasses.includes(r));

console.log(found);
<div class="showroom-layout-toggle" data-switch-group="showroom_layout" data-switch-target=".test" data-switch-cookie>
  <button class="grid-toggle" data-switch data-switch-class="grid-view">Grid</button>
  <button class="grid-toggle" data-switch data-switch-class="list-view">List</button>
</div>

<div class="test list-view">Hello</div>

Not that it matters much for inputs this small, but for this general situation I'd prefer to make a Set to make the computational complexity O(n) instead of O(n^2):

const switchesClasses = new Set(
  Array.from(
    document.querySelectorAll('[data-switch]'),
    x => x.dataset.switchClass
  )
);


const found = Array.from(document.querySelector('.test').classList)
  .find(r => switchesClasses.has(r));

console.log(found);
<div class="showroom-layout-toggle" data-switch-group="showroom_layout" data-switch-target=".test" data-switch-cookie>
  <button class="grid-toggle" data-switch data-switch-class="grid-view">Grid</button>
  <button class="grid-toggle" data-switch data-switch-class="list-view">List</button>
</div>

<div class="test list-view">Hello</div>
CertainPerformance
  • 356,069
  • 52
  • 309
  • 320