可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I am trying to find the index of all the instances of an element, say, "Nano", in a JavaScript array.
var Cars = ["Nano", "Volvo", "BMW", "Nano", "VW", "Nano"];
I tried jQuery.inArray, or similarly, .indexOf(), but it only gave the index of the last instance of the element, i.e. 5 in this case.
How do I get it for all instances?
回答1:
The .indexOf()
method has an optional second parameter that specifies the index to start searching from, so you can call it in a loop to find all instances of a particular value:
function getAllIndexes(arr, val) { var indexes = [], i = -1; while ((i = arr.indexOf(val, i+1)) != -1){ indexes.push(i); } return indexes; } var indexes = getAllIndexes(Cars, "Nano");
You don't really make it clear how you want to use the indexes, so my function returns them as an array (or returns an empty array if the value isn't found), but you could do something else with the individual index values inside the loop.
UPDATE: As per VisioN's comment, a simple for loop would get the same job done more efficiently, and it is easier to understand and therefore easier to maintain:
function getAllIndexes(arr, val) { var indexes = [], i; for(i = 0; i < arr.length; i++) if (arr[i] === val) indexes.push(i); return indexes; }
回答2:
Another alternative solution is to use Array.prototype.reduce()
:
["Nano","Volvo","BMW","Nano","VW","Nano"].reduce(function(a, e, i) { if (e === 'Nano') a.push(i); return a; }, []); // [0, 3, 5]
N.B.: Check the browser compatibility for reduce
method and use polyfill if required.
回答3:
Another approach using Array.prototype.map() and Array.prototype.filter():
var indices = array.map((e, i) => e === value ? i : '').filter(String)
回答4:
We can use Stack and push "i" into the stack every time we encounter the condition "arr[i]==value"
Check this:
static void getindex(int arr[], int value) { Stack<Integer>st= new Stack<Integer>(); int n= arr.length; for(int i=n-1; i>=0 ;i--) { if(arr[i]==value) { st.push(i); } } while(!st.isEmpty()) { System.out.println(st.peek()+" "); st.pop(); } }
回答5:
findIndex
retrieves only the first index which matches callback output. You can implement your own findIndexes
by extending Array , then casting your arrays to the new structure .
class EnhancedArray extends Array { findIndexes(where) { return this.reduce((a, e, i) => (where(e, i) ? a.concat(i) : a), []); } } /*----Working with simple data structure (array of numbers) ---*/ //existing array let myArray = [1, 3, 5, 5, 4, 5]; //cast it : myArray = new EnhancedArray(...myArray); //run console.log( myArray.findIndexes((e) => e===5) ) /*----Working with Array of complex items structure-*/ let arr = [{name: 'Ahmed'}, {name: 'Rami'}, {name: 'Abdennour'}]; arr= new EnhancedArray(...arr); console.log( arr.findIndexes((o) => o.name.startsWith('A')) )
回答6:
If you intend to use underscore/lodash, you could do
var Cars = ["Nano", "Volvo", "BMW", "Nano", "VW", "Nano"]; _.chain(Cars).map((v, i)=> [i, v === "Nano"]).filter(v=>v[1]).map(v=>v[0]).value() [0, 3, 5]