ฉันมีอ็อบเจกต์ JavaScript Array อย่างง่าย ๆ ที่มีตัวเลขไม่กี่ตัว
[267, 306, 108]
มีฟังก์ชั่นที่จะหาจำนวนมากที่สุดในอาเรย์นี้หรือไม่?
ฉันมีอ็อบเจกต์ JavaScript Array อย่างง่าย ๆ ที่มีตัวเลขไม่กี่ตัว
[267, 306, 108]
มีฟังก์ชั่นที่จะหาจำนวนมากที่สุดในอาเรย์นี้หรือไม่?
คำตอบ:
Array.max = function( array ){
return Math.max.apply( Math, array );
};
คำเตือน : เนื่องจากจำนวนอาร์กิวเมนต์สูงสุดมีน้อยถึง 65535 ใน VMs บางตัวใช้สำหรับลูปถ้าคุณไม่แน่ใจว่าอาร์เรย์มีขนาดเล็ก
apply
โทรสามารถล้างออกได้อย่างง่ายดายมาก
RangeError: Maximum call stack size exceeded.
คุณสามารถใช้ฟังก์ชั่นนำไปใช้เพื่อโทรMath.max :
var array = [267, 306, 108];
var largest = Math.max.apply(Math, array); // 306
มันทำงานอย่างไร?
ใช้ฟังก์ชั่นที่ใช้ในการเรียกใช้ฟังก์ชันอีกด้วยบริบทที่กำหนดและข้อโต้แย้งให้เป็นอาร์เรย์ ฟังก์ชัน min และ max สามารถรับจำนวนอาร์กิวเมนต์ที่ป้อนเข้าโดยพลการได้: Math.max (val1, val2, ... , valN)
ดังนั้นถ้าเราเรียกว่า:
Math.min.apply(Math, [1,2,3,4]);
ฟังก์ชั่นใช้จะดำเนินการ:
Math.min(1,2,3,4);
โปรดทราบว่าพารามิเตอร์แรกบริบทไม่สำคัญสำหรับฟังก์ชั่นเหล่านี้เนื่องจากพวกเขาเป็นแบบคงที่พวกเขาจะทำงานโดยไม่คำนึงถึงสิ่งที่จะถูกส่งผ่านเป็นบริบท
ไวยากรณ์ที่ง่ายที่สุดด้วยตัวดำเนินการสเปรดใหม่:
var arr = [1, 2, 3];
var max = Math.max(...arr);
ที่มา: Mozilla MDN
ฉันไม่ใช่ผู้เชี่ยวชาญ JS แต่ฉันต้องการดูว่าวิธีการเหล่านี้ซ้อนกันอย่างไรนี่เป็นวิธีปฏิบัติที่ดีสำหรับฉัน ฉันไม่รู้ว่านี่เป็นเทคนิคที่เหมาะสมในการทดสอบประสิทธิภาพเหล่านี้หรือไม่ แต่ฉันเพิ่งลองทดสอบพวกเขาทีละอย่างตามที่คุณเห็นในรหัสของฉัน
การเรียงลำดับและรับค่า 0 เป็นวิธีที่แย่ที่สุด (และจะปรับเปลี่ยนลำดับของอาร์เรย์ซึ่งอาจไม่เป็นที่ต้องการ) สำหรับคนอื่น ๆ ความแตกต่างนั้นเล็กน้อยมากยกเว้นว่าคุณกำลังพูดถึงดัชนีนับล้าน
ผลลัพธ์โดยเฉลี่ยของการรันห้าครั้งด้วยอาเรย์ 100,000 ดัชนีของตัวเลขสุ่ม:
var performance = window.performance
function findmax(array)
{
var max = 0,
a = array.length,
counter
for (counter=0;counter<a;counter++)
{
if (array[counter] > max)
{
max = array[counter]
}
}
return max
}
function findBiggestNumber(num) {
var counts = []
var i
for (i = 0; i < num; i++) {
counts.push(Math.random())
}
var a, b
a = performance.now()
var biggest = counts.reduce(function(highest, count){
return highest > count ? highest : count
}, 0)
b = performance.now()
console.log('reduce took ' + (b - a) + ' ms to run')
a = performance.now()
var biggest2 = Math.max.apply(Math, counts)
b = performance.now()
console.log('Math.max.apply took ' + (b - a) + ' ms to run')
a = performance.now()
var biggest3 = counts.sort(function(a,b){return b-a;})[0]
b = performance.now()
console.log('sorting and getting the 0th value took ' + (b - a) + ' ms to run')
a = performance.now()
var biggest4 = counts.reduce(function(highest, count){
return Math.max(highest,count)
}, 0)
b = performance.now()
console.log('Math.max within reduce() took ' + (b - a) + ' ms to run')
a = performance.now()
var biggest5 = findmax(counts)
b = performance.now()
console.log('custom findmax function took ' + (b - a) + ' ms to run')
console.log(biggest + '-' + biggest2 + '-' + biggest3 + '-' + biggest4 + '-' + biggest5)
}
findBiggestNumber(1E5)
jsperf tests
สำหรับข้างต้น
ฉันได้พบว่าสำหรับอาร์เรย์ที่ใหญ่กว่า (องค์ประกอบประมาณ ~ 100k) มันจ่ายจริง ๆ เพียงแค่วนซ้ำอาร์เรย์ด้วยfor
ลูปต่ำต้อยประสิทธิภาพดีกว่า ~ 30% Math.max.apply()
:
function mymax(a)
{
var m = -Infinity, i = 0, n = a.length;
for (; i != n; ++i) {
if (a[i] > m) {
m = a[i];
}
}
return m;
}
คุณสามารถเรียงลำดับจากมากไปหาน้อยและรับรายการแรก:
[267, 306, 108].sort(function(a,b){return b-a;})[0]
sort(function(a,b){return b-a;})
[...].sort().pop()
เกี่ยวกับสิ่งนี้:
var arr = [1,2,3,4];
var largest = arr.reduce(function(x,y){
return (x > y) ? x : y;
});
console.log(largest);
วิธีการเกี่ยวกับการใช้Array.reduce ?
[0,1,2,3,4].reduce(function(previousValue, currentValue){
return Math.max(previousValue,currentValue);
});
-Infinity
ค่าเริ่มต้นควรจะกำหนดให้
คำตอบเกือบทั้งหมดใช้Math.max.apply()
ซึ่งดีและสวยงาม แต่มีข้อ จำกัด
อาร์กิวเมนต์ของฟังก์ชันถูกวางลงบนสแต็กซึ่งมีข้อเสีย - ขีด จำกัด ดังนั้นถ้าอาร์เรย์ของคุณใหญ่กว่าขีด จำกัด มันจะล้มเหลวด้วยRangeError: Maximum call stack size exceeded.
หากต้องการค้นหาขนาดสแตกการโทรฉันใช้รหัสนี้:
var ar = [];
for (var i = 1; i < 100*99999; i++) {
ar.push(1);
try {
var max = Math.max.apply(Math, ar);
} catch(e) {
console.log('Limit reached: '+i+' error is: '+e);
break;
}
}
มันพิสูจน์แล้วว่าเป็นที่ใหญ่ที่สุดใน Firefox บนเครื่องของฉัน - 591519 ซึ่งหมายความว่าถ้าคุณอาเรย์ที่มีมากกว่า591,519รายการMath.max.apply()
จะมีผลในRangeError
ทางออกที่ดีที่สุดสำหรับปัญหานี้คือวิธีวนซ้ำ (เครดิต: https://developer.mozilla.org/ ):
max = -Infinity, min = +Infinity;
for (var i = 0; i < numbers.length; i++) {
if (numbers[i] > max)
max = numbers[i];
if (numbers[i] < min)
min = numbers[i];
}
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/max
const inputArray = [ 1, 3, 4, 9, 16, 2, 20, 18];
const maxNumber = Math.max(...inputArray);
console.log(maxNumber);
การหาค่าสูงสุดและต่ำสุดวิธีที่ง่ายและคู่มือ รหัสนี้เร็วกว่าMath.max.apply
มาก ฉันได้ลองตัวเลขมากถึง 1,000,000 ชุด
function findmax(array)
{
var max = 0;
var a = array.length;
for (counter=0;counter<a;counter++)
{
if (array[counter] > max)
{
max = array[counter];
}
}
return max;
}
function findmin(array)
{
var min = array[0];
var a = array.length;
for (counter=0;counter<a;counter++)
{
if (array[counter] < min)
{
min = array[counter];
}
}
return min;
}
findmax()
ให้ผลลัพธ์ที่ผิดถ้ามีเพียงจำนวนลบในอาร์เรย์ findmin()
ให้ผลลัพธ์ที่ไม่ถูกต้องสำหรับอาเรย์ที่ว่างเปล่า
ในการหาจำนวนที่มากที่สุดในอาเรย์ที่คุณต้องการใช้งานMath.max(...arrayName);
มันจะเป็นดังนี้
let myArr = [1, 2, 3, 4, 5, 6];
console.log(Math.max(...myArr));
หากต้องการเรียนรู้เพิ่มเติมเกี่ยวกับMath.max
:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/max
ใช่แน่นอนอยู่: Math.max.apply(null,[23,45,67,-45])
และผลตอบแทน67
;
ซับง่าย
[].sort().pop()
อย่าลืมว่าห่อสามารถทำได้ด้วยการFunction.prototype.bind
ให้คุณ "all-พื้นเมือง" ฟังก์ชั่น
var aMax = Math.max.apply.bind(Math.max, Math);
aMax([1, 2, 3, 4, 5]); // 5
คุณสามารถขยายArray
ให้มีฟังก์ชั่นนี้และทำให้มันเป็นส่วนหนึ่งของทุกอาร์เรย์
Array.prototype.max = function(){return Math.max.apply( Math, this )};
myArray = [1,2,3];
console.log( myArray.max() );
คุณยังสามารถใช้forEach :
var maximum = Number.MIN_SAFE_INTEGER;
var array = [-3, -2, 217, 9, -8, 46];
array.forEach(function(value){
if(value > maximum) {
maximum = value;
}
});
console.log(maximum); // 217
การใช้ - Array.prototype.reduce()
ยอดเยี่ยม!
[267, 306, 108].reduce((acc,val)=> (acc>val)?acc:val)
โดยที่ACC = ตัวสะสมและval = ค่าปัจจุบัน ;
var a = [267, 306, 108].reduce((acc,val)=> (acc>val)?acc:val);
console.log(a);
คุณสามารถลองสิ่งนี้
var arr = [267,306,108];
var largestNum = 0;
for(i=0;i<arr.length;i++) {
if(arr[i]>largest){
var largest = arr[i];
}
}
console.log(largest);
ฉันเพิ่งเริ่มต้นกับ JS แต่ฉันคิดว่าวิธีนี้จะดี:
var array = [34, 23, 57, 983, 198];<br>
var score = 0;
for(var i = 0; i = array.length; i++) {
if(array[ i ] > score) {
score = array[i];
}
}
array
มีตัวเลขที่เป็นลบเท่านั้น
var max = [];
for(var i=0; arr.length>i; i++ ){
var arra = arr[i];
var largest = Math.max.apply(Math, arra);
max.push(largest);
}
return max;
var tmax = Math.max.apply(Math, max)
หรือดีกว่ายังใช้การปิดของฟังก์ชั่นเช่นวงในstackoverflow.com/a/54980012/7438857 ด้วยการปรับเปลี่ยนนี้ก็เป็นคำตอบที่ดีกว่าที่จะเป็นคำถามที่แยกต่างหากอย่างไรคุณ "พบจำนวนมากที่สุดในอาร์เรย์หลายมิติ" หรือที่stackoverflow.com/questions/32616910/... WIP: jsfiddle.net/jamesray/3cLu9for/8
เรียกใช้สิ่งนี้:
Array.prototype.max = function(){
return Math.max.apply( Math, this );
};
และตอนนี้ลอง[3,10,2].max()
ส่งคืน10
ค้นหาค่า Max และ Min โดยใช้ Bubble Sort
var arr = [267, 306, 108];
for(i=0, k=0; i<arr.length; i++) {
for(j=0; j<i; j++) {
if(arr[i]>arr[j]) {
k = arr[i];
arr[i] = arr[j];
arr[j] = k;
}
}
}
console.log('largest Number: '+ arr[0]);
console.log('Smallest Number: '+ arr[arr.length-1]);
ลองสิ่งนี้
function largestNum(arr) {
var currentLongest = arr[0]
for (var i=0; i< arr.length; i++){
if (arr[i] > currentLongest){
currentLongest = arr[i]
}
}
return currentLongest
}
เป็นต่อ @ Quasimondo ของความคิดเห็นซึ่งดูเหมือนว่าจะมีการพลาดส่วนใหญ่ที่อยู่ด้านล่างดูเหมือนว่าจะมีประสิทธิภาพที่ดีที่สุดตามที่แสดงไว้ที่นี่: https://jsperf.com/finding-maximum-element-in-an-array โปรดทราบว่าในขณะที่อาร์เรย์ในคำถามประสิทธิภาพอาจไม่ส่งผลอย่างมีนัยสำคัญสำหรับประสิทธิภาพการทำงานของอาร์เรย์ขนาดใหญ่จะมีความสำคัญมากขึ้นและอีกครั้งตามที่ระบุไว้โดยใช้Math.max()
จะไม่ทำงานแม้ว่าความยาวของอาร์เรย์จะมากกว่า 65535 ดูคำตอบนี้ด้วย
function largestNum(arr) {
var d = data;
var m = d[d.length - 1];
for (var i = d.length - 1; --i > -1;) {
if (d[i] > m) m = d[i];
}
return m;
}
วิธีแบบเรียกซ้ำในวิธีการใช้ตัวดำเนินการประกอบ
const findMax = (arr, max, i) => arr.length === i ? max :
findMax(arr, arr[i] > max ? arr[i] : max, ++i)
const arr = [5, 34, 2, 1, 6, 7, 9, 3];
const max = findMax(arr, arr[0], 0)
console.log(max);
for/of
ทางออกหนึ่งวง:
const numbers = [2, 4, 6, 8, 80, 56, 10];
const findMax = (...numbers) => {
let currentMax = numbers[0]; // 2
for (const number of numbers) {
if (number > currentMax) {
console.log(number, currentMax);
currentMax = number;
}
}
console.log('Largest ', currentMax);
return currentMax;
};
findMax(...numbers);
Math.max(...[267, 306, 108]);