ค้นหาเว็บไซต์

javascript - วิธีหาตำแหน่งดัชนีของทุกการเกิดขึ้นขององค์ประกอบในอาร์เรย์?


ฉันกำลังพยายามหาดัชนีของทุกตัวอย่างขององค์ประกอบหนึ่ง สมมติว่า 'Nano' ในอาร์เรย์ของ JavaScript

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

ฉันลองใช้ jQuery.inArray หรือคล้ายกันคือ .indexOf() แต่ก็ได้เพียงดัชนีของอิลิเมนต์ครั้งสุดท้ายเท่านั้น เช่น ในกรณีนี้คือ 5

ฉันจะได้มันสำหรับทุกอินสแตนซ์ได้อย่างไร?

คำตอบ #1

เมธอด .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;
}

คำตอบ #2

อีกทางเลือกหนึ่งคือการใช้ 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 หากจำเป็น.

คำตอบ #3

วิธีการอีกแบบหนึ่งโดยใช้ Array.prototype.map() และ Array.prototype.filter():

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

คำตอบ #4

คุณสามารถเขียนโซลูชันที่อ่านง่ายสำหรับเรื่องนี้ได้โดยใช้ทั้ง 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 : []);

คำตอบ #5

วิธีที่ง่ายขึ้นด้วยสไตล์ 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); // []

คำตอบ #6

ฉันแค่อยากอัปเดตด้วยวิธีง่ายๆ อีกวิธีหนึ่ง

คุณสามารถใช้วิธี forEach ได้เช่นกัน

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

var result = [];

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

บทความที่เกี่ยวข้อง