簡體   English   中英

如何查找數組中所有元素出現的索引?

[英]How to find the indexes of all occurrences of an element in array?

我正在嘗試在 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]

注意:檢查reduce方法的瀏覽器兼容性,並在需要時使用polyfill

另一種使用Array.prototype.map()Array.prototype.filter() 的方法

var indices = array.map((e, i) => e === value ? i : '').filter(String)

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); // []

您可以使用mapfilter編寫一個簡單易讀的解決方案:

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 : []);

我只想用另一種簡單的方法進行更新。

您也可以使用 forEach 方法。

var Cars = ["Nano", "Volvo", "BMW", "Nano", "VW", "Nano"];

var result = [];

Cars.forEach((car, index) => car === 'Nano' ? result.push(index) : null)

注意:MDN 給出了一個使用 while 循環方法

var indices = [];
var array = ['a', 'b', 'a', 'c', 'a', 'd'];
var element = 'a';
var idx = array.indexOf(element);
while (idx != -1) {
  indices.push(idx);
  idx = array.indexOf(element, idx + 1);
}

我不會說它比其他答案更好。 只是有趣。

const indexes = cars
    .map((car, i) => car === "Nano" ? i : null)
    .filter(i => i !== null)

這對我有用:

let array1 = [5, 12, 8, 130, 44, 12, 45, 12, 56];
let numToFind = 12
let indexesOf12 = [] // the number whose occurrence in the array we want to find

array1.forEach(function(elem, index, array) {
    if (elem === numToFind) {indexesOf12.push(index)}
    return indexesOf12
})

console.log(indexesOf12) // outputs [1, 5, 7]

只是分享另一種方法,您也可以使用函數生成器來實現結果:

 function findAllIndexOf(target, needle) { return [].concat(...(function*(){ for (var i = 0; i < target.length; i++) if (target[i] === needle) yield [i]; })()); } var target = "hellooooo"; var target2 = ['w','o',1,3,'l','o']; console.log(findAllIndexOf(target, 'o')); console.log(findAllIndexOf(target2, 'o'));

["a", "b", "a", "b"]
   .map((val, index) => ({ val, index }))
   .filter(({val, index}) => val === "a")
   .map(({val, index}) => index)

=> [0, 2]

您可以使用 Polyfill

if (!Array.prototype.filterIndex) {
Array.prototype.filterIndex = function (func, thisArg) {

    'use strict';
    if (!((typeof func === 'Function' || typeof func === 'function') && this))
        throw new TypeError();

    let len = this.length >>> 0,
        res = new Array(len), // preallocate array
        t = this, c = 0, i = -1;

    let kValue;
    if (thisArg === undefined) {
        while (++i !== len) {
            // checks to see if the key was set
            if (i in this) {
                kValue = t[i]; // in case t is changed in callback
                if (func(t[i], i, t)) {
                    res[c++] = i;
                }
            }
        }
    }
    else {
        while (++i !== len) {
            // checks to see if the key was set
            if (i in this) {
                kValue = t[i];
                if (func.call(thisArg, t[i], i, t)) {
                    res[c++] = i;
                }
            }
        }
    }

    res.length = c; // shrink down array to proper size
    return res;
};

}

像這樣使用它:

[2,23,1,2,3,4,52,2].filterIndex(element => element === 2)

result: [0, 3, 7]

findIndex僅檢索與回調輸出匹配的第一個索引。 您可以通過擴展 Array 來實現您自己的findIndexes ,然后將您的數組轉換為新結構。

 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')) )

每次遇到條件“arr[i]==value”時,我們可以使用Stack並將“i”壓入堆棧

檢查這個:

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(); 
    }
}

當兩個參數都作為數組傳遞時


    function getIndexes(arr, val) {
        var indexes = [], i;
        for(i = 0; i < arr.length; i++){
    for(j =0; j< val.length; j++) {
     if (arr[i] === val[j])
                indexes.push(i);
    }
    }    
        return indexes;
    }

此外, findIndex()將很有用:

var cars = ['Nano', 'Volvo', 'BMW', 'Nano', 'VW', 'Nano'];

const indexes = [];
const searchedItem = 'NaNo';

cars.findIndex((value, index) => {
  if (value.toLowerCase() === searchedItem.toLowerCase()) {
    indexes.push(index);
  }
});

console.log(indexes); //[ 0, 3, 5 ]

獎金:

此自定義解決方案使用Object.entries()forEach()

var cars = ['Nano', 'Volvo', 'BMW', 'Nano', 'VW', 'Nano'];

const indexes = [];
const searchableItem = 'Nano';

Object.entries(cars).forEach((item, index) => {
  if (item[1].toLowerCase() === searchableItem.toLowerCase())
    indexes.push(index);
});

console.log(indexes);

注意:我沒有運行運行所有測試

如果您打算使用下划線/破折號,則可以

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]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM