1

I have an array that consists of several words and I am finding a particular word. My current solution, which is below, works perfectly fine for small array. But if this array contains lets say 10,000 words then my solution would require a lot memory and CPU resources as it is not efficient enough. How can I make my code better in terms of performance and should take less resources for a large array in JavaScript?

var words = ['apple', 'orange', 'ananas', 'banana', 'mango', 'lemon', 'tomato'];

function search (term) {
  for (var i = 0, len = words.length; i < len; i++) {
    if (words[i] === term) {
      console.log(words[i] + ' is found at ' + i);
    }
  }
}

search('tomato');
Om3ga
  • 30,465
  • 43
  • 141
  • 221

3 Answers3

6

Prepopulate a dictionary (object) with the words as keys. Then a lookup is merely dict[term].

var words = ['apple', 'orange', 'ananas', 'banana', 'mango', 'lemon', 'tomato'];
var dict = {};

function prepopulate() {
    words.forEach(function(word, i) { dict[word] = i; });
}

function search (term) {
    if (term in dict) {
        console.log(term + ' is found at ' + dict[term]);
    }
}

prepopulate();
search('tomato');
  • Could you also give us time complexity of this solution? – Om3ga Dec 18 '14 at 07:43
  • Depends on the engine's algorithms, but I'm guessing that the time for pre-population is O(n), and the time for lookup is around O(1) or slightly worse. –  Dec 18 '14 at 07:45
  • I am looking for O(log n) or something better. But your solution could be the one that I could use. Could you make it a bit better? – Om3ga Dec 18 '14 at 07:46
  • 1
    It **is** better than O(log n), it's O(1). The prepopulation is a one-time cost amortized over many lookups. –  Dec 18 '14 at 07:47
  • But O(n) is not better. – Om3ga Dec 18 '14 at 07:48
  • O(n) happens **once** and once only. It's a minor investment which serves to vastly reduce the time for your actual lookups, which I assume you are going to do many times. –  Dec 18 '14 at 07:50
2

Well, don't know if I'm missing something but why can't you use indexOf?

function search (term) {
   console.log(term + " is found at " + words.indexOf(term));
}
Amit Joki
  • 58,320
  • 7
  • 77
  • 95
  • IndexOf uses bruteforce algorithm that means its time complexity would be O(n2). – Om3ga Dec 18 '14 at 07:37
  • @2619 It's native and fast and will be definitely faster than looping and finding as it's built-in. You're using something similar I suppose – Amit Joki Dec 18 '14 at 07:39
  • I am using similar that is why I am looking for better solution but indexOf definitely not the solution to my question. – Om3ga Dec 18 '14 at 07:41
0

Well, the consensus answer is that the fastest way to iterate through an array is with the very same for loop that you used, so nice work. But, I made a jsPerf for this specific case, and...

It turns out the while loop is quicker! In fact, it seems to be a whole 90% quicker. Not sure why that's the case, but the proof is all there (at least in my browser). Granted, I assumed that if you had multiple instances of the value in the array, you would want to know all the indices that matched it, not just the first occurrence, so the return value is an array as well. Anyway, here is the winning code block:

//Note that I have 2 instances of tomato!
var words = ['apple', 'orange', 'tomato', 'ananas', 'banana', 'mango', 'lemon', 'tomato'];

//Gave the function two arguments to make it more generic
function search (arr, term) {
  var i, indices = [];
  while (i < arr.length) {
    if (arr[i] === term) {
      indices.push(i);
    }
    i++;
  }
  return indices;
}

search(words, 'tomato');
Community
  • 1
  • 1
AlexZ
  • 11,515
  • 3
  • 28
  • 42