ฉันมีสิ่งนี้:
var arr = [0, 21, 22, 7];
วิธีใดที่ดีที่สุดในการคืนค่าดัชนีที่มีค่าสูงสุดเป็นตัวแปรอื่น
ฉันมีสิ่งนี้:
var arr = [0, 21, 22, 7];
วิธีใดที่ดีที่สุดในการคืนค่าดัชนีที่มีค่าสูงสุดเป็นตัวแปรอื่น
arr.indexOf(Math.max(...arr))
เป็นยัง . คำตอบของฉัน แต่ฟังก์ชั่นหนึ่ง)
คำตอบ:
นี่อาจเป็นวิธีที่ดีที่สุดเนื่องจากเชื่อถือได้และใช้ได้กับเบราว์เซอร์รุ่นเก่า:
function indexOfMax(arr) {
if (arr.length === 0) {
return -1;
}
var max = arr[0];
var maxIndex = 0;
for (var i = 1; i < arr.length; i++) {
if (arr[i] > max) {
maxIndex = i;
max = arr[i];
}
}
return maxIndex;
}
นอกจากนี้ยังมีซับเดียว:
let i = arr.indexOf(Math.max(...arr));
มันทำการเปรียบเทียบได้มากเป็นสองเท่าเท่าที่จำเป็นและจะโยนRangeError
อาร์เรย์ขนาดใหญ่แม้ว่า ฉันชอบฟังก์ชั่น
const max = arr.reduce((m, n) => Math.max(m, n))
[...arr.keys()].filter(i => arr[i] === max)
[...arr.keys()]
แสดงข้อผิดพลาด:unexpected token
ในบรรทัดเดียวและอาจเร็วกว่านั้นarr.indexOf(Math.max.apply(Math, arr))
:
var a = [0, 21, 22, 7];
var indexOfMaxValue = a.reduce((iMax, x, i, arr) => x > arr[iMax] ? i : iMax, 0);
document.write("indexOfMaxValue = " + indexOfMaxValue); // prints "indexOfMaxValue = 2"
ที่ไหน:
iMax
- ดัชนีที่ดีที่สุดจนถึงตอนนี้ (ดัชนีขององค์ประกอบสูงสุดในการวนซ้ำครั้งแรกiMax = 0
เนื่องจากอาร์กิวเมนต์ที่สองreduce()
คือ0
เราไม่สามารถข้ามอาร์กิวเมนต์ที่สองreduce()
ในกรณีของเราได้)x
- องค์ประกอบที่ทดสอบในปัจจุบันจากอาร์เรย์i
- ดัชนีที่ทดสอบในปัจจุบันarr
- อาร์เรย์ของเรา ( [0, 21, 22, 7]
)เกี่ยวกับreduce()
วิธีการนี้ (จาก "JavaScript: The Definitive Guide" โดย David Flanagan):
ลด () รับสองอาร์กิวเมนต์ ประการแรกคือฟังก์ชั่นที่ดำเนินการลด หน้าที่ของฟังก์ชันการลดนี้คือการรวมหรือลดค่าสองค่าให้เป็นค่าเดียวและส่งคืนค่าที่ลดลงนั้น
ฟังก์ชันที่ใช้กับการลด () แตกต่างจากฟังก์ชันที่ใช้กับ forEach () และแผนที่ () ค่าดัชนีและอาร์เรย์ที่คุ้นเคยจะถูกส่งผ่านเป็นอาร์กิวเมนต์ที่สองสามและสี่ อาร์กิวเมนต์แรกคือผลการสะสมของการลดจนถึงขณะนี้ ในการเรียกใช้ฟังก์ชันครั้งแรกอาร์กิวเมนต์แรกนี้คือค่าเริ่มต้นที่คุณส่งผ่านเป็นอาร์กิวเมนต์ที่สองเพื่อลด () ในการโทรครั้งต่อ ๆ ไปเป็นค่าที่ส่งคืนโดยการเรียกใช้ฟังก์ชันก่อนหน้านี้
เมื่อคุณเรียกใช้การลด () โดยไม่มีค่าเริ่มต้นจะใช้องค์ประกอบแรกของอาร์เรย์เป็นค่าเริ่มต้น ซึ่งหมายความว่าการเรียกใช้ฟังก์ชันการลดครั้งแรกจะมีองค์ประกอบอาร์เรย์แรกและที่สองเป็นอาร์กิวเมนต์ที่หนึ่งและที่สอง
arr.reduce((bestIndexSoFar, currentlyTestedValue, currentlyTestedIndex, array) => currentlyTestedValue > array[bestIndexSoFar] ? currentlyTestedIndex : bestIndexSoFar, 0);
ซึ่งสามารถอธิบายเป็น: สำทับอาร์เรย์ที่เริ่มต้นจากดัชนี 0 (พารามิเตอร์ 2) ถ้าcurrentlyTestedValueสูงกว่ามูลค่าขององค์ประกอบที่ที่bestIndexSoFarแล้วกลับcurrentlyTestedIndexจะซ้ำไปเป็นbestIndexSoFar
this.methods.reduce((methodIndex, currentMethod, currentMethodIndex, methods) => currentMethod.price <= methods[methodIndex].price ? currentMethodIndex : methodIndex, 0)
นี่เป็นตัวอย่างโลกแห่งความจริงที่ผมดำเนินการ:
นี่คืออีกวิธีหนึ่งหากคุณใช้ ES6 โดยใช้ตัวดำเนินการกระจาย:
var arr = [0, 21, 22, 7];
const indexOfMaxValue = arr.indexOf(Math.max(...arr));
reduce
:[1,2,5,0,4].reduce((a,b,i) => a[0] < b ? [b,i] : a, [Number.MIN_VALUE,-1])
//[5,2]
สิ่งนี้จะส่งคืน[5e-324, -1]
หากอาร์เรย์ว่างเปล่า หากคุณต้องการเพียงแค่ดัชนีให้ใส่[1]
หลัง
>
และMAX_VALUE
):[1,2,5,0,4].reduce((a,b,i) => a[0] > b ? [b,i] : a, [Number.MAX_VALUE,-1])
//[0, 3]
ถ้าฉันเข้าใจผิดฉันจะบอกว่าให้เขียนฟังก์ชันของคุณเอง
function findIndexOfGreatest(array) {
var greatest;
var indexOfGreatest;
for (var i = 0; i < array.length; i++) {
if (!greatest || array[i] > greatest) {
greatest = array[i];
indexOfGreatest = i;
}
}
return indexOfGreatest;
}
findIndexOfGreatest( [-5, 0, -10, -1])
ส่งกลับ 3 ...
หากคุณใช้ขีดล่างคุณสามารถใช้ซับในสั้น ๆ นี้ได้:
_.indexOf(arr, _.max(arr))
ขั้นแรกจะพบค่าของรายการที่ใหญ่ที่สุดในอาร์เรย์ในกรณีนี้คือ 22 จากนั้นจะส่งคืนดัชนีที่ 22 อยู่ภายในอาร์เรย์ในกรณีนี้ 2
function findIndicesOf(haystack, needle)
{
var indices = [];
var j = 0;
for (var i = 0; i < haystack.length; ++i) {
if (haystack[i] == needle)
indices[j++] = i;
}
return indices;
}
ผ่านarray
ไปhaystack
และจะMath.max(...array)
needle
สิ่งนี้จะให้องค์ประกอบสูงสุดทั้งหมดของอาร์เรย์และสามารถขยายได้มากขึ้น (เช่นคุณต้องหาค่าต่ำสุดด้วย)
ในการทำงานของ @VFDan ให้เสร็จสมบูรณ์ฉันได้เปรียบเทียบ 3 วิธี: หนึ่งที่ยอมรับ (ลูปที่กำหนดเอง) ลดและค้นหา (สูงสุด (arr)) บนอาร์เรย์ 10,000 ลอย
หากคุณต้องการให้โค้ดของคุณทำงานเร็วอย่าใช้ indexOf (max) ลดได้ แต่ใช้ลูปที่กำหนดเองหากคุณต้องการการแสดงที่ดีที่สุด
คุณสามารถเรียกใช้เกณฑ์มาตรฐานนี้บนเบราว์เซอร์อื่นโดยใช้ลิงก์นี้: https://jsben.ch/wkd4c
var arr=[0,6,7,7,7];
var largest=[0];
//find the largest num;
for(var i=0;i<arr.length;i++){
var comp=(arr[i]-largest[0])>0;
if(comp){
largest =[];
largest.push(arr[i]);
}
}
alert(largest )//7
//find the index of 'arr'
var arrIndex=[];
for(var i=0;i<arr.length;i++){
var comp=arr[i]-largest[0]==0;
if(comp){
arrIndex.push(i);
}
}
alert(arrIndex);//[2,3,4]
แก้ไข: เมื่อหลายปีก่อนฉันให้คำตอบว่ามันไม่ชัดเจนเจาะจงเกินไปและซับซ้อนเกินไป ผมกำลังแก้ไข ฉันชอบคำตอบที่ใช้งานได้ข้างต้นสำหรับปัจจัยที่เป็นระเบียบ แต่อ่านไม่ออก แต่ถ้าฉันคุ้นเคยกับจาวาสคริปต์มากกว่าฉันก็อาจจะชอบมันด้วยเช่นกัน
รหัสหลอก:
ติดตามดัชนีที่มีค่ามากที่สุด สมมติว่าดัชนี 0 มีขนาดใหญ่ที่สุดในตอนแรก เปรียบเทียบกับดัชนีปัจจุบัน อัปเดตดัชนีที่มีค่ามากที่สุดหากจำเป็น
รหัส:
var mountains = [3, 1, 5, 9, 4];
function largestIndex(array){
var counter = 1;
var max = 0;
for(counter; counter < array.length; counter++){
if(array[max] < array[counter]){
max = counter;
}
}
return max;
}
console.log("index with largest value is: " +largestIndex(mountains));
// index with largest value is: 3
หากคุณสร้างสำเนาของอาร์เรย์และเรียงลำดับจากมากไปหาน้อยองค์ประกอบแรกของสำเนาจะมีขนาดใหญ่ที่สุด กว่าคุณจะพบดัชนีในอาร์เรย์เดิม
var sorted = [...arr].sort((a,b) => b - a)
arr.indexOf(sorted[0])
ความซับซ้อนของเวลาคือ O (n) สำหรับสำเนา O (n * log (n)) สำหรับการเรียงลำดับและ O (n) สำหรับ indexOf
หากคุณต้องการทำเร็วขึ้นคำตอบของ Ry คือ O (n)
เวอร์ชันเสถียรของฟังก์ชันนี้มีลักษณะดังนี้:
// not defined for empty array
function max_index(elements) {
var i = 1;
var mi = 0;
while (i < elements.length) {
if (!(elements[i] < elements[mi]))
mi = i;
i += 1;
}
return mi;
}