Pages

Monday, June 6, 2016

Rewrite Underscore's indexOf function

var _ = {};



  _.each =  function(collection, iterator){

  if(Array.isArray(collection)){
    for(var i = 0; i < collection.length; i ++){
      iterator(collection[i], i, collection);
    }
  }
  else{
    for(var key in collection){
      iterator(collection[key], key, collection);
    }
  }
}





_.indexOf = function(array, target) {
   
    var result = -1

    _.each(array, function(item, index) {
        if (item === target && result === -1) {
            result = index
        }
    })

    return result
}


I've included _.each above _.indexOf because indexOf uses each.

IndexOf searches an array for for a target.  If that target is found, it returns the index at which the object is found, otherwise it returns -1.

First it defines two parameters, array and target.  Then it creates the local variable results and sets its value to -1.

Then _.each is called.  The same array that is fed to indexOf is fed to each, and a function is hard wired into each.  The function that is hard wired in calls for arguments, item and index.  (If only the item was required, then there would only be one parameter there.)

Then a conditional statement is made which says that if the item === the target is true and the result === -1 is true, then result changes its value to the index that is associated with that item.  Finally, the results returned.

So, let's walk through how it would work with this array called numbers.

var numbers = [1,2,3];

var test = _.indexOf(numbers, 3);
In this case test will be equal to = 2.

This is because first result = -1.

The function each test whether 1 is equal to the target which is 3.  That will equate to false, so the result = index statement inside the blocks will not happen, in fact, since there are no more if statement, absolutely nothing will happen, and each will iterate to the next item in the array.   Next, the same thing will happen with 2.  Now, 3 === target will equate to true so the right side of the && operator will be checked : result === -1 will equate to true so result = index will take place, the index in this case is 2.  With the each loops finished, the return result statement will be run, and it will return 2.


Maybe you have a couple of questions?

Question 1 = Why set  var result = -1 ?

First the var keyword is used to make result a local variable.  It's best to keep all variables inside a function local, incase there is a global variable named result.  By using the var keyword inside the function, even if there is a global variable with the same name, the function will use the local
one.  The reason it's given a value of -1 is so if the target is never found, then -1 will be returned.  A return value of -1 means that the target does not exist inside the array.

Question 2 = Why do you need && result = -1.

The function indexOf returns the index of the first instance of the target.  So, say there are several matches in an array like this one: var numbers = [2,6,4,5,2,4,5,4].

If this array were run with a target of 4, the index that matches the target would change each time if it weren't for the && result = -1 statement.

However, as soon as item === target = true "And" result === -1 === true, then result is set to that first 4s index number.  The next time there is a match, result will not equal -1, therefore it will not change the value of result.

Eventually, when each has finished iterating through the array, result will be returned and that value will be the index number of the first match with the target.


No comments:

Post a Comment