admin管理员组文章数量:1391969
When using indexOf, I can just locate the position of the first appearance:
for example:
a=[1,2,4,2];
b=a.indexOf(2);
alert(b) //returns 1
Is there any alternative function to indexOf to find the both position or am I missing something? I am looking for the shortcut. Of course, I can always go for writing a simple look to find it.
When using indexOf, I can just locate the position of the first appearance:
for example:
a=[1,2,4,2];
b=a.indexOf(2);
alert(b) //returns 1
Is there any alternative function to indexOf to find the both position or am I missing something? I am looking for the shortcut. Of course, I can always go for writing a simple look to find it.
Share Improve this question asked Jul 11, 2013 at 17:25 Jack_of_All_TradesJack_of_All_Trades 11.5k20 gold badges64 silver badges95 bronze badges4 Answers
Reset to default 5indexOf takes a second argument (the starting index)
So a.indexOf(2,2)
would give you 3
To generalize, if x = a.indexOf(2)
, then the next instance is a.indexOf(2, x+1)
With one loop :
function indexesOf(arr, target) {
let index = [];
// For each element, index pushed in index[]
arr.forEach((el, i) => {
if (el === target) index.push(i)
});
return index;
}
alert(indexesOf([1, 2, 4, 2], 2)); // -> 1, 3
With two loops :
function indexesOf(arr, target) {
// Map matching elements to their index, and others to null.
return arr.map(function (el, i) { return (el === target) ? i : null; })
// Throw out the nulls.
.filter(function (x) { return x !== null; });
}
alert(indexesOf([1, 2, 4, 2], 2)); // -> 1, 3
As you are using a recent ECMAScript 5 method then you may want to consider using Array.map
and Array.filter
along with a new Harmony proposed method Object.is
Javascript
var func = {}.is,
is;
if (typeof func === "function") {
is = func;
} else {
is = function is(x, y) {
if (x === y) {
if (x === 0) {
return 1 / x === 1 / y;
}
return true;
}
var x1 = x,
y1 = y;
return x !== x1 && y !== y1;
};
}
function indexesOf(array, value) {
if (!Array.isArray(array)) {
throw new TypeError("First attribute must be an array.");
}
return array.map(function (element, index) {
if (is(value, element)) {
return index;
}
}).filter(function (element) {
return typeof element === "number";
});
}
var test = [1, 2, 4, 2];
console.log(indexesOf(test, 2));
Output
[1, 3]
On jsfiddle
Update: I have been castigated in the past for using loops when people have the strong belief "but this is exactly what these new methods are designed for". So, I am going to present alternative single loop solutions too.
ECMAScript 5 Array.reduce
Javascript
function indexesOf(array, value) {
if (!Array.isArray(array)) {
throw new TypeError("First attribute must be an array.");
}
return array.reduce(function (previous, current, index) {
if (is(value, current)) {
previous.push(index);
}
return previous;
}, []);
}
On jsfiddle
ECMAScript 5 Array.forEach
Javascript
function indexesOf(array, value) {
if (!Array.isArray(array)) {
throw new TypeError("First attribute must be an array.");
}
var indexes = [];
array.forEach(function (element, index) {
if (is(value, element)) {
indexes.push(index);
}
});
return indexes.
}
On jsfiddle
ECMAScript 5 Array.indexOf
Note: this method is unable to find the indexes of NaN
Could also use Array.lastIndexOf
and work in reverse
Javascript
function indexesOf(array, value) {
if (!Array.isArray(array)) {
throw new TypeError("First attribute must be an array.");
}
var index = array.indexOf(value),
indexes = [];
while (index !== -1) {
indexes.push(index);
index = array.indexOf(value, index + 1);
}
return indexes;
}
On jsfiddle
standard for
Javascript
function indexesOf(array, value) {
if ({}.toString.call(array) !== "[object Array]") {
throw new TypeError("First attribute must be an array.");
}
var indexes = [],
length,
index;
for (index = 0, length = array.length; index < length; index += 1) {
if (array.hasOwnProperty(index) && is(value, array[index])) {
indexes.push(index);
}
}
return indexes;
}
On jsfiddle
Standard while
Javascript
function indexesOf(array, value) {
if ({}.toString.call(array) !== "[object Array]") {
throw new TypeError("First attribute must be an array.");
}
var length = array.length,
indexes = []
index = 0;
while (index < length) {
if (array.hasOwnProperty(index) && is(value, array[index])) {
indexes.push(index);
}
index += 1;
}
return indexes;
}
On jsfiddle
Standard for...in
Note: This is NOT remended, but should be fine.
Why is using “for…in” with array iteration such a bad idea?
Javascript
function indexesOf(array, value) {
if ({}.toString.call(array) !== "[object Array]") {
throw new TypeError("First attribute must be an array.");
}
var indexes = [],
prop;
for (prop in array) {
if (array.hasOwnProperty(prop) && is(+prop, prop >>> 0) && is(value, array[prop])) {
indexes.push(+prop);
}
}
return indexes;
}
On jsfiddle
Note: All of the solutions here handle both dense and sparse arrays.
And finally a jsperf paring all of these solutions.
lastIndexOf() gives the index of last occurence.
But if want an array of indices containing all the occurences of a particular element(2 in your case), you have to write a loop.
本文标签: indexOf similar function to return multiple appearance in javascriptStack Overflow
版权声明:本文标题:indexOf similar function to return multiple appearance in javascript - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744711902a2621178.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论