Is there indexOf in javascript to search for an array with a custom compare function

I need the index of the first value in the array that matches the user-defined comparison function.

A very nice underscorej has a β€œfind” function that returns the first value when the function returns true, but I need it to return an index. Is there a version of indexOf available somewhere where I can pass in the function used for comparison?

Thanks for any suggestions!

+22
javascript indexof
Sep 10 '12 at 17:28
source share
8 answers

The Underscore method is used here - this increases the main Underscore function with the one that takes the iterator function:

// save a reference to the core implementation var indexOfValue = _.indexOf; // using .mixin allows both wrapped and unwrapped calls: // _(array).indexOf(...) and _.indexOf(array, ...) _.mixin({ // return the index of the first array element passing a test indexOf: function(array, test) { // delegate to standard indexOf if the test isn't a function if (!_.isFunction(test)) return indexOfValue(array, test); // otherwise, look for the index for (var x = 0; x < array.length; x++) { if (test(array[x])) return x; } // not found, return fail value return -1; } }); _.indexOf([1,2,3], 3); // 2 _.indexOf([1,2,3], function(el) { return el > 2; } ); // 2 
+26
Sep 10
source share
β€” -

You can do something like this:

 Array.prototype.myIndexOf = function(f) { for(var i=0; i<this.length; ++i) { if( f(this[i]) ) return i; } return -1; }; 

Regarding the Christian comment: if you redefine the standard JavaScript method with a custom signature from a different signature and different functions, then something bad will probably happen. This is especially true if you are using third-party libraries that may depend on the original, say Array.proto.indexOf. So yes, you probably want to call it something else.

+7
Sep 10 '12 at 17:35
source share

There is a suggestion for Array.prototype.findIndex() in Harmony (ECMAScript 6). It is currently implemented in Firefox and Safari. Here's a polyfill, courtesy of the Mozilla Developer Network :

 if (!Array.prototype.findIndex) { Array.prototype.findIndex = function(predicate) { if (this == null) { throw new TypeError('Array.prototype.find called on null or undefined'); } if (typeof predicate !== 'function') { throw new TypeError('predicate must be a function'); } var list = Object(this); var length = list.length >>> 0; var thisArg = arguments[1]; var value; for (var i = 0; i < length; i++) { value = list[i]; if (predicate.call(thisArg, value, i, list)) { return i; } } return -1; }; } 
+6
Dec 08 '14 at 12:35
source share

As others have noted, it’s easy enough to collapse your own, which you can save in your specific use case:

 // Find the index of the first element in array // meeting specified condition. // var findIndex = function(arr, cond) { var i, x; for (i in arr) { x = arr[i]; if (cond(x)) return parseInt(i); } }; var moreThanTwo = function(x) { return x > 2 } var i = findIndex([1, 2, 3, 4], moreThanTwo) 

Or if you are a CoffeeScripter:

 findIndex = (arr, cond) -> for i, x of arr return parseInt(i) if cond(x) 
+3
Jul 05 '14 at 16:06
source share

The javascript array method filter returns a subset of the array that returns true from the passed function.

 var arr= [1, 2, 3, 4, 5, 6], first= arr.filter(function(itm){ return itm>3; })[0]; alert(first); if you must support IE before #9 you can 'shim' Array.prototype.filter- Array.prototype.filter= Array.prototype.filter || function(fun, scope){ var T= this, A= [], i= 0, itm, L= T.length; if(typeof fun== 'function'){ while(i<L){ if(i in T){ itm= T[i]; if(fun.call(scope, itm, i, T)) A[A.length]= itm; } ++i; } } return A; } 
+1
Sep 10 '12 at 18:14
source share

How about such a search function?

 (function () { if (!Array.prototype._find) { Array.prototype._find = function (value) { var i = -1, j = this.length; if (typeof(value)=="function") for(; (++i < j) && !value(this[i]);); else for(; (++i < j) && !(this[i] === value);); return i!=j ? i : -1; } } }()); 
+1
May 27 '13 at 12:41
source share

Here comes the coffee version of the nrabinowitz code .

 # save a reference to the core implementation indexOfValue = _.indexOf # using .mixin allows both wrapped and unwrapped calls: # _(array).indexOf(...) and _.indexOf(array, ...) _.mixin ({ # return the index of the first array element passing a test indexOf: (array, test) -> # delegate to standard indexOf if the test isn't a function if (!_.isFunction(test)) return indexOfValue(array, test) # otherwise, look for the index for item, i in array return i if (test(item)) # not found, return fail value return -1 }) 
+1
Aug 6 '13 at 1:51
source share

using underscore. I came up with something copied from their implementation using _.any:

 findIndex = function (obj, iterator, context) { var idx; _.any(obj, function (value, index, list) { if (iterator.call(context, value, index, list)) { idx = index; return true; } }); return idx; }; 

Do you think you have better solutions?

0
Sep 10 '12 at 17:40
source share



All Articles