0

I'm trying to find if an element of one list exists in another longer list. Is there an efficient way to do this. So far I have:

var list1 = ['A1', 'A3', 'B7'];
var list2 = ['A1', 'A4', 'A19', 'A8'];
for (i=0; i<list1.length; i++){
     for (k=0;k<list2;k++){
          if (list1[i]==list2[k]){
              var matchIndex = k;
      }
    }
}

but i Feel like there has to be a more efficient way to sort through this than with this method. Is there a command like np.where in python for JavaScript (I'm new to JS)?

  • 1
    Maybe this ? https://stackoverflow.com/questions/16312528/check-if-an-array-contains-any-element-of-another-array-in-javascript – Met Br Mar 03 '21 at 19:56

1 Answers1

0

You can use JavaScript's built in Array prototype methods i.e. find, findIndex, includes, and some.

const
  existsIn          = (sm, lg) => lg.some(e => sm.includes(e)),
  firstMatch        = (sm, lg) => lg.find(e => sm.includes(e)),
  indexOfFirstMatch = (sm, lg) => lg.findIndex(e => sm.includes(e)),
  larger            = ['A19', 'A4', 'A1', 'A8'],
  smaller           = ['A1', 'A3', 'B7'];

console.log(existsIn(smaller, larger));          // true
console.log(firstMatch(smaller, larger));        // 2
console.log(indexOfFirstMatch(smaller, larger)); // A1

Alternatively, you could cache the smaller list, prior to checking the larger list. This alleviates the use of calling Array.prototype.includes on the smaller list.

const
  lookup            = a => a.reduce((r, e, i) => ({ ...r, [e]: i }), {}),
  existsIn          = (sm, lg) => (lu => lg.some(e => lu[e] != null))(lookup(sm)),
  firstMatch        = (sm, lg) => (lu => lg.find(e => lu[e] != null))(lookup(sm)),
  indexOfFirstMatch = (sm, lg) => (lu => lg.findIndex(e => lu[e] != null))(lookup(sm)),
  larger            = ['A19', 'A4', 'A1', 'A8'],
  smaller           = ['A1', 'A3', 'B7'];

console.log(existsIn(smaller, larger));          // true
console.log(firstMatch(smaller, larger));        // 2
console.log(indexOfFirstMatch(smaller, larger)); // A1

You could further modify this into a thunk/closure, but you must recache, if the smaller list if modified.

const
  lookup  = a => a.reduce((r, e, i) => ({ ...r, [e]: i }), {}),
  finder  = sm => (lu => () => ({
    existsIn          : lg => lg.some(e => lu[e] != null),
    firstMatch        : lg => lg.find(e => lu[e] != null),
    indexOfFirstMatch : lg => lg.findIndex(e => lu[e] != null)
  }))(lookup(sm))(),  
  larger  = ['A19', 'A4', 'A1', 'A8'],
  smaller = ['A1', 'A3', 'B7'],
  find    = finder(smaller);

console.log(find.existsIn(larger));          // true
console.log(find.firstMatch(larger));        // 2
console.log(find.indexOfFirstMatch(larger)); // A1
Mr. Polywhirl
  • 42,981
  • 12
  • 84
  • 132