javascript 中是否有 indexOf 可以使用自定义比较函数搜索数组
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12356642/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is there an indexOf in javascript to search an array with custom compare function
提问by Peter T.
I need the indexof the first value in the array, that matches a custom compare function.
我需要数组中第一个值的索引,它与自定义比较函数匹配。
The very nice underscorejhas a "find" function that returns the first value where a function returns true, but I would need this that returns the index instead. Is there a version of indexOf available somewhere, where I can pass a function used to comparing?
非常好的underscorej有一个“find”函数,它返回函数返回 true 的第一个值,但我需要它来返回索引。某处是否有可用的 indexOf 版本,我可以在那里传递用于比较的函数?
Thanks for any suggestions!
感谢您的任何建议!
回答by nrabinowitz
Here's the Underscore way to do it - this augments the core Underscore function with one that accepts an iterator function:
这是 Underscore 的方法 - 这用一个接受迭代器函数的函数来扩充核心 Underscore 函数:
// 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
回答by Husky
There's a standard functionin ECMAScript 2015 for Array.prototype.findIndex()
. Currently it's implemented in all major browsers apart from Internet Explorer.
ECMAScript 2015 中有一个标准函数用于Array.prototype.findIndex()
. 目前,它已在除 Internet Explorer 之外的所有主要浏览器中实现。
Here's a polyfill, courtesy of the Mozilla Developer Network:
这是一个 polyfill,由Mozilla 开发者网络提供:
// https://tc39.github.io/ecma262/#sec-array.prototype.findIndex
if (!Array.prototype.findIndex) {
Object.defineProperty(Array.prototype, 'findIndex', {
value: function(predicate) {
// 1. Let O be ? ToObject(this value).
if (this == null) {
throw new TypeError('"this" is null or not defined');
}
var o = Object(this);
// 2. Let len be ? ToLength(? Get(O, "length")).
var len = o.length >>> 0;
// 3. If IsCallable(predicate) is false, throw a TypeError exception.
if (typeof predicate !== 'function') {
throw new TypeError('predicate must be a function');
}
// 4. If thisArg was supplied, let T be thisArg; else let T be undefined.
var thisArg = arguments[1];
// 5. Let k be 0.
var k = 0;
// 6. Repeat, while k < len
while (k < len) {
// a. Let Pk be ! ToString(k).
// b. Let kValue be ? Get(O, Pk).
// c. Let testResult be ToBoolean(? Call(predicate, T, ? kValue, k, O ?)).
// d. If testResult is true, return k.
var kValue = o[k];
if (predicate.call(thisArg, kValue, k, o)) {
return k;
}
// e. Increase k by 1.
k++;
}
// 7. Return -1.
return -1;
},
configurable: true,
writable: true
});
}
回答by Nathan Andrew Mullenax
You could 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 Christian's comment: if you override a standard JavaScript method with a custom one with a differentthe same signature and different functionality, bad thing will likely happen. This is especially true if you're pulling in 3rd party libraries which may depend on the original, say, Array.proto.indexOf. So yeah, you probably want to call it something else.
关于 Christian 的评论:如果您使用具有不同相同签名和不同功能的自定义方法覆盖标准 JavaScript 方法,则可能会发生坏事。如果您要引入可能依赖于原始库的 3rd 方库,例如 Array.proto.indexOf,则尤其如此。所以是的,你可能想称它为别的东西。
回答by joyrexus
As others have noted, easy enough to roll your own, which you can keep short and simple for your particular 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're a CoffeeScripter:
或者,如果您是 CoffeeScripter:
findIndex = (arr, cond) ->
for i, x of arr
return parseInt(i) if cond(x)
回答by kennebec
The javascript array method filterreturns a subset of the array that return true from the function passed.
javascript 数组方法过滤器返回数组的子集,该子集从传递的函数返回 true。
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;
}
回答by 23W
How about such find 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;
}
}
}());
回答by Shiva Huang
Here comes the coffeescript version of nrabinowitz's code.
这是nrabinowitz代码的coffeescript 版本。
# 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
})
回答by Peter T.
using underscore I came up with something copied from their find implementation using _.any:
使用下划线,我想出了一些使用 _.any 从他们的 find 实现中复制的东西:
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;
};
What do you think - do you have any better solutions?
你怎么看 - 你有更好的解决方案吗?