我试图在 JavaScript 数组中找到元素的所有实例的索引,比如“Nano”。
var Cars = ["Nano", "Volvo", "BMW", "Nano", "VW", "Nano"];
我尝试了jQuery.inArray或类似的.indexOf(),但它只给出了元素的最后一个实例的索引,即在这种情况下为 5。
我如何为所有实例获取它?
我试图在 JavaScript 数组中找到元素的所有实例的索引,比如“Nano”。
var Cars = ["Nano", "Volvo", "BMW", "Nano", "VW", "Nano"];
我尝试了jQuery.inArray或类似的.indexOf(),但它只给出了元素的最后一个实例的索引,即在这种情况下为 5。
我如何为所有实例获取它?
该.indexOf()
方法有一个可选的第二个参数,用于指定开始搜索的索引,因此您可以在循环中调用它以查找特定值的所有实例:
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");
您并没有真正明确如何使用索引,因此我的函数将它们作为数组返回(如果找不到值,则返回一个空数组),但是您可以对各个索引值执行其他操作循环内。
更新:根据 VisioN 的评论,简单的 for 循环可以更有效地完成相同的工作,并且更易于理解,因此更易于维护:
function getAllIndexes(arr, val) {
var indexes = [], i;
for(i = 0; i < arr.length; i++)
if (arr[i] === val)
indexes.push(i);
return indexes;
}
另一种替代解决方案是使用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]
另一种使用Array.prototype.map()和Array.prototype.filter() 的方法:
var indices = array.map((e, i) => e === value ? i : '').filter(String)
您可以使用map
和编写一个简单易读的解决方案filter
:
const nanoIndexes = Cars
.map((car, i) => car === 'Nano' ? i : -1)
.filter(index => index !== -1);
编辑:如果您不需要支持 IE/Edge(或正在转译您的代码),ES2019 为我们提供了flatMap,它可以让您以简单的单行方式执行此操作:
const nanoIndexes = Cars.flatMap((car, i) => car === 'Nano' ? i : []);
es6风格更简单的方式。
const indexOfAll = (arr, val) => arr.reduce((acc, el, i) => (el === val ? [...acc, i] : acc), []);
//Examples:
var cars = ["Nano", "Volvo", "BMW", "Nano", "VW", "Nano"];
indexOfAll(cars, "Nano"); //[0, 3, 5]
indexOfAll([1, 2, 3, 1, 2, 3], 1); // [0,3]
indexOfAll([1, 2, 3], 4); // []