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)
