search in array for string match

Sunil Meena :

What i have

var sentence = 'My country is India';
var array = ['Intel,' 'Goa', 'Green Day', 'India', 'Ice', 'India'];

Result i need

  index = array.indexOf(sentence); // it should return 3

And this is what i tried it works but its very slow and freezes and stop working when use big data

words = sentence.split(' ');
var i;
for (i = 0; i < words.length; i++) {
    w = words[i];
    a = array.indexOf(w);
    console.log(a);
}

Update : i tried below solutions but still stop working i am working on google audio to speech so its run continually some one speeak so sentence array triggers again and again i think this is why its freezing after some point

Update 2: In above example i search for single word i.e. "India" but what if i its more than one word like if its a person name like "Neil Armstrong" then split method will not work.

CertainPerformance :

Array#indexOf is an O(n) operation - the interpreter has to iterate through the whole array, worst-case, to see if there's a match or not. When done in a loop, this increases the computational complexity to O(n ^ 2), which will be slow.

You can use a Set instead - Set#has has a complexity of O(1) (reducing the overall complexity to O(n)):

var sentence = 'My country is India';
var array = ['Intel', 'Goa', 'Green Day', 'India', 'Ice'];

const words = new Set(sentence.split(' '));
console.log(
  array.findIndex(word => words.has(word))
);

Or an object (object key lookup is O(1) too):

var sentence = 'My country is India';
var array = ['Intel', 'Goa', 'Green Day', 'India', 'Ice'];

const words = Object.fromEntries(
  sentence.split(' ').map(key => [key])
);
console.log(
  array.findIndex(word => words.hasOwnProperty(word))
);

See how you can also use findIndex to make the code much more concise.

If the item you're hoping to match is composed of two words, also match every occurrence of 2 words next to each other:

var sentence = 'My country is Green Day';
var array = ['Intel', 'Goa', 'Green Day', 'India', 'Ice'];

const words = new Set(sentence.split(' '));
const pattern = /(?=(\S+ \S+))/g;
while (true) {
  const match = pattern.exec(sentence);
  if (!match) {
    break;
  }
  words.add(match[1]);
  pattern.lastIndex++;
}
console.log(
  array.findIndex(word => words.has(word))
);

For a more general solution, you can check the input array to identify which number of words you need to collect, then for each number, iterate over the sentence words to add them to a Set:

var sentence = 'My country is Green Day';
var array = ['Intel', 'Goa', 'Green Day', 'India', 'Ice'];

const combinationsNeeded = new Set();
for (const substr of array) {
  combinationsNeeded.add(substr.split(' ').length);
}
const wordsSet = new Set();
const sentenceWords = sentence.split(' ');
for (const comb of combinationsNeeded) {
  let endIndex = comb;
  for (let i = 0; i + comb <= sentenceWords.length; i++) {
    // uncomment the below to see all the words wordsSet gets
    // console.log(sentenceWords.slice(i, i + comb).join(' '));
    wordsSet.add(sentenceWords.slice(i, i + comb).join(' '));
  }
}

console.log(
  array.findIndex(substr => wordsSet.has(substr))
);

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=17063&siteId=1