Làm cách nào tôi có thể dễ dàng có được phần tử tối thiểu hoặc tối đa của một mảng JavaScript?
Ví dụ Psuedocode:
let array = [100, 0, 50]
array.min() //=> 0
array.max() //=> 100
Math.max.apply(null, [2,5,16,1])
Làm cách nào tôi có thể dễ dàng có được phần tử tối thiểu hoặc tối đa của một mảng JavaScript?
Ví dụ Psuedocode:
let array = [100, 0, 50]
array.min() //=> 0
array.max() //=> 100
Math.max.apply(null, [2,5,16,1])
Câu trả lời:
Làm thế nào về việc tăng đối tượng Array tích hợp để sử dụng Math.max
/ Math.min
thay vào đó:
Array.prototype.max = function() {
return Math.max.apply(null, this);
};
Array.prototype.min = function() {
return Math.min.apply(null, this);
};
Đây là một JSFiddle .
Tăng cường biện pháp xây dựng-in có thể gây ra va chạm với các thư viện khác (Một số người xem), vì vậy bạn có thể thoải mái hơn với chỉ apply
'ing Math.xxx()
để mảng của bạn trực tiếp:
var min = Math.min.apply(null, arr),
max = Math.max.apply(null, arr);
Cách khác, giả sử trình duyệt của bạn hỗ trợ ECMAScript 6, bạn có thể sử dụng toán tử trải rộng có chức năng tương tự như apply
phương thức:
var min = Math.min( ...arr ),
max = Math.max( ...arr );
null
hoặc Math
hoặc {}
bất cứ điều gì đến apply()
hoặc call()
không có liên quan đến kết quả. Math.max
không nên cũng không nên tham khảo this
nội bộ.
Math.max.apply(null, $.makeArray(array));
.max
hoặc .min
phương thức trong tương lai. Kịch bản hoàn hảo thực tế: Bạn sử dụng câu trả lời này. Trong năm 2016, ES7 hoặc ES8 spec Array.max
và Array.min
. Không giống như phiên bản này, chúng hoạt động trên chuỗi. Đồng nghiệp tương lai của bạn cố gắng lấy chuỗi mới nhất theo thứ tự bảng chữ cái trong một mảng với .max()
phương thức gốc được chứng minh bằng tài liệu hiện có , nhưng bí ẩn NaN
. Vài giờ sau, cô tìm thấy mã này, chạy a git blame
và nguyền rủa tên của bạn.
var max_of_array = Math.max.apply(Math, array);
Để thảo luận đầy đủ, hãy xem: http://aaroncrane.co.uk/2008/11/javascript_max_api/
Math.max.apply(Math, array)
và là Math.max.apply(null, array)
gì? Blog nói "... bạn cũng phải nói lại một cách thừa thãi max
thuộc về Math
...", nhưng có vẻ như tôi không phải làm như vậy (bằng cách đặt đối số đầu tiên apply
là as null
).
Math.max(a,b)
, Math
được thông qua dưới dạng this
giá trị, vì vậy có thể có ý nghĩa tương tự khi gọi với apply
. Nhưng Math.max
không sử dụng this
giá trị, vì vậy bạn có thể vượt qua bất kỳ giá trị nào bạn muốn.
Đối với các mảng lớn (~ 10⁷ phần tử) Math.min
và Math.max
cả hai đều tạo ra lỗi sau trong Node.js.
RangeError: Vượt quá kích thước ngăn xếp cuộc gọi tối đa
Một giải pháp mạnh mẽ hơn là không thêm mọi phần tử vào ngăn xếp cuộc gọi mà thay vào đó là truyền một mảng:
function arrayMin(arr) {
return arr.reduce(function (p, v) {
return ( p < v ? p : v );
});
}
function arrayMax(arr) {
return arr.reduce(function (p, v) {
return ( p > v ? p : v );
});
}
Nếu bạn lo lắng về tốc độ, đoạn mã sau nhanh hơn ~ 3 lần Math.max.apply
trên máy tính của tôi. Xem http://jsperf.com/min-and-max-in-array/2 .
function arrayMin(arr) {
var len = arr.length, min = Infinity;
while (len--) {
if (arr[len] < min) {
min = arr[len];
}
}
return min;
};
function arrayMax(arr) {
var len = arr.length, max = -Infinity;
while (len--) {
if (arr[len] > max) {
max = arr[len];
}
}
return max;
};
Nếu mảng của bạn chứa chuỗi thay vì số, bạn cũng cần ép buộc chúng thành số. Đoạn mã dưới đây thực hiện điều đó, nhưng nó làm chậm mã xuống ~ 10 lần trên máy của tôi. Xem http://jsperf.com/min-and-max-in-array/3 .
function arrayMin(arr) {
var len = arr.length, min = Infinity;
while (len--) {
if (Number(arr[len]) < min) {
min = Number(arr[len]);
}
}
return min;
};
function arrayMax(arr) {
var len = arr.length, max = -Infinity;
while (len--) {
if (Number(arr[len]) > max) {
max = Number(arr[len]);
}
}
return max;
};
min
và max
cho phần tử cuối cùng và giảm số lần lặp xuống 1 ( while(--len)
);)
very different results
bạn đã làm điều này 5 năm sau)
reduce
giải pháp là chậm nhất. Ngay cả khi bạn làm việc với một mảng có hàng triệu phần tử, tốt hơn là sử dụng tiêu chuẩn cho vòng lặp . Xem câu trả lời của tôi để biết thêm.
Sử dụng toán tử trải rộng (ES6)
Math.max(...array); // the same with "min" => Math.min(...array);
If no arguments are given, the result is -∞.
// For regular arrays:
var max = Math.max(...arrayOfNumbers);
// For arrays with tens of thousands of items:
let max = testArray[0];
for (let i = 1; i < testArrayLength; ++i) {
if (testArray[i] > max) {
max = testArray[i];
}
}
Các tài liệu MDN chính thức vềMath.max()
vấn đề này đã bao gồm vấn đề này:
Hàm sau sử dụng Function.prototype.apply () để tìm phần tử tối đa trong một mảng số.
getMaxOfArray([1, 2, 3])
tương đương vớiMath.max(1, 2, 3)
, nhưng bạn có thể sử dụnggetMaxOfArray()
trên các mảng được xây dựng theo chương trình với mọi kích thước.function getMaxOfArray(numArray) { return Math.max.apply(null, numArray); }
Hoặc với toán tử trải rộng mới , việc lấy tối đa của một mảng trở nên dễ dàng hơn rất nhiều.
var arr = [1, 2, 3]; var max = Math.max(...arr);
Theo MDN, các apply
giải pháp lan truyền có giới hạn 65536 xuất phát từ giới hạn số lượng đối số tối đa:
Nhưng hãy cẩn thận: khi sử dụng áp dụng theo cách này, bạn sẽ gặp rủi ro vượt quá giới hạn độ dài đối số của công cụ JavaScript. Hậu quả của việc áp dụng một hàm có quá nhiều đối số (nghĩ rằng hơn hàng chục nghìn đối số) khác nhau giữa các công cụ ( JavaScriptCore có giới hạn đối số được mã hóa cứng là 65536 ), bởi vì giới hạn (thực sự là bản chất của bất kỳ ngăn xếp quá lớn nào hành vi) là không xác định. Một số động cơ sẽ ném một ngoại lệ. Nghiêm trọng hơn, những người khác sẽ tùy ý giới hạn số lượng đối số thực sự được truyền cho hàm được áp dụng. Để minh họa trường hợp sau này: nếu một công cụ như vậy có giới hạn bốn đối số (giới hạn thực tế dĩ nhiên cao hơn đáng kể), thì sẽ như thể các đối số 5, 6, 2, 3 đã được thông qua để áp dụng trong các ví dụ trên, chứ không phải là mảng đầy đủ.
Họ thậm chí còn cung cấp một giải pháp lai không thực sự có hiệu suất tốt so với các giải pháp khác. Xem kiểm tra hiệu suất dưới đây để biết thêm.
Năm 2019 giới hạn thực tế là kích thước tối đa của ngăn xếp cuộc gọi . Đối với các trình duyệt máy tính để bàn dựa trên Chromium hiện đại, điều này có nghĩa là khi tìm thấy min / max có apply
hoặc trải rộng, thực tế kích thước tối đa cho các số chỉ các mảng là ~ 120000 . Ở trên này, sẽ có một lỗi tràn ngăn xếp và lỗi sau sẽ được đưa ra:
RangeError: Vượt quá kích thước ngăn xếp cuộc gọi tối đa
Với tập lệnh bên dưới (dựa trên bài đăng trên blog này ), bằng cách bắt lỗi đó, bạn có thể tính giới hạn cho môi trường cụ thể của mình.
Cảnh báo! Chạy tập lệnh này mất thời gian và tùy thuộc vào hiệu suất của hệ thống của bạn, nó có thể làm chậm hoặc làm sập trình duyệt / hệ thống của bạn!
let testArray = Array.from({length: 10000}, () => Math.floor(Math.random() * 2000000));
for (i = 10000; i < 1000000; ++i) {
testArray.push(Math.floor(Math.random() * 2000000));
try {
Math.max.apply(null, testArray);
} catch (e) {
console.log(i);
break;
}
}
Dựa trên thử nghiệm trong nhận xét của EscapeNetscape , tôi đã tạo một số điểm chuẩn kiểm tra 5 phương thức khác nhau trên một mảng chỉ có số ngẫu nhiên với 100000 mục .
Năm 2019, kết quả cho thấy vòng lặp tiêu chuẩn (mà BTW không có giới hạn kích thước) là nhanh nhất ở mọi nơi. apply
và lan truyền đến rất gần sau đó, sau đó là giải pháp lai của MDN sau đó reduce
là chậm nhất.
Hầu như tất cả các bài kiểm tra đều cho kết quả như nhau, ngoại trừ một bài kiểm tra có kết quả chậm nhất.
Nếu bạn đẩy mạnh mảng của mình để có 1 triệu mục, mọi thứ bắt đầu bị phá vỡ và bạn bị bỏ lại với vòng lặp tiêu chuẩn như một giải pháp nhanh và reduce
chậm hơn.
Math.max.apply(Math, arr)
tương thích 'tối đa'.
(...)
và apply
sẽ thất bại hoặc trả về kết quả sai nếu mảng có quá nhiều phần tử [...] Giải pháp rút gọn không có vấn đề này" Thử nghiệm Chrome, FF, Edge và IE11 có vẻ như đó là ok cho một mảng có giá trị lên tới 100k. (Đã thử nghiệm trên Win10 và các trình duyệt mới nhất: Chrome 110k, Firefox 300k, Edge 400k, IE11 150k).
Nếu bạn hoang tưởng như tôi về việc sử dụng Math.max.apply
(có thể gây ra lỗi khi được cung cấp các mảng lớn theo MDN ), hãy thử điều này:
function arrayMax(array) {
return array.reduce(function(a, b) {
return Math.max(a, b);
});
}
function arrayMin(array) {
return array.reduce(function(a, b) {
return Math.min(a, b);
});
}
Hoặc, trong ES6:
function arrayMax(array) {
return array.reduce((a, b) => Math.max(a, b));
}
function arrayMin(array) {
return array.reduce((a, b) => Math.min(a, b));
}
Rất tiếc, các hàm ẩn danh là không cần thiết (thay vì sử dụng Math.max.bind(Math)
vì reduce
không chỉ truyền a
và b
chức năng của nó, mà còn i
là một tham chiếu đến chính mảng đó, vì vậy chúng tôi phải đảm bảo chúng tôi cũng không cố gắng gọi max
chúng.
Math.max(...array)
?
apply
, và do đó có cùng nhược điểm (giới hạn đối số tối đa).
function arrayMax(array) { return array.reduce(function(a, b) { return Math.max(a, b); }); // <--------- missing ) }
Math.min()
không có giá trị, trả về Infinity
, vì vậy các hàm này có thể sử dụng reduce(..., Infinity)
để khớp với hành vi đó. Tôi thích nó ném một ngoại lệ mặc dù (như hiện tại), bởi vì lấy tối thiểu của một mảng trống dường như là một lỗi.
.apply
thường được sử dụng khi có ý định gọi hàm matrixdic với danh sách các giá trị đối số, vd
Các Math.max([value1[,value2, ...]])
hàm trả về lớn nhất trong số zero hoặc nhiều số.
Math.max(10, 20); // 20
Math.max(-10, -20); // -10
Math.max(-10, 20); // 20
Các Math.max()
phương pháp không cho phép bạn để vượt qua trong một mảng. Nếu bạn có một danh sách các giá trị mà bạn cần lấy giá trị lớn nhất, thông thường bạn sẽ gọi hàm này bằng Function.prototype.apply () , vd
Math.max.apply(null, [10, 20]); // 20
Math.max.apply(null, [-10, -20]); // -10
Math.max.apply(null, [-10, 20]); // 20
Tuy nhiên, như là ECMAScript 6, bạn có thể sử dụng toán tử trải rộng :
Toán tử trải rộng cho phép một biểu thức được mở rộng ở những nơi có nhiều đối số (đối với các lệnh gọi hàm) hoặc nhiều phần tử (đối với các mảng bằng chữ) được mong đợi.
Sử dụng toán tử trải rộng, ở trên có thể được viết lại như sau:
Math.max(...[10, 20]); // 20
Math.max(...[-10, -20]); // -10
Math.max(...[-10, 20]); // 20
Khi gọi một hàm bằng toán tử matrixdic, bạn thậm chí có thể thêm các giá trị bổ sung, vd
Math.max(...[10, 20], 50); // 50
Math.max(...[-10, -20], 50); // 50
Tặng kem:
Điều hành lây lan cho phép bạn sử dụng cú pháp theo nghĩa đen mảng để tạo mảng mới trong tình huống mà trong ES5 bạn sẽ cần phải rơi trở lại mã bắt buộc, sử dụng kết hợp push
, splice
vv
let foo = ['b', 'c'];
let bar = ['a', ...foo, 'd', 'e']; // ['a', 'b', 'c', 'd', 'e']
concat
bởi hầu hết các lập trình viên bởi vì nó cho phép bạn duy trì một kiểu dòng duy nhất.
Hai cách ngắn hơn và dễ dàng:
let arr = [2, 6, 1, 0]
Cách 1 :
let max = Math.max.apply(null, arr)
Cách 2 :
let max = arr.reduce(function(a, b) {
return Math.max(a, b);
});
0
bạn có thể sử dụng [0].concat(arr)
hoặc với cú pháp lây lan [0, ...arr]
(thay cho 'mảng')
Một giải pháp đơn giản để tìm giá trị tối thiểu trên một Array
phần tử là sử dụng Array
hàm nguyên mẫu reduce
:
A = [4,3,-9,-2,2,1];
A.reduce((min, val) => val < min ? val : min, A[0]); // returns -9
hoặc sử dụng hàm Math.Min () tích hợp của JavaScript (cảm ơn @Tenflex):
A.reduce((min,val) => Math.min(min,val), A[0]);
Cái này đặt min
thành A[0]
, và sau đó kiểm tra A[1]...A[n]
xem nó có hoàn toàn nhỏ hơn hiện tại không min
. Nếu A[i] < min
sau đó min
được cập nhật lên A[i]
. Khi tất cả các phần tử mảng đã được xử lý, min
kết quả sẽ được trả về.
EDIT : Bao gồm vị trí của giá trị tối thiểu:
A = [4,3,-9,-2,2,1];
A.reduce((min, val) => val < min._min ? {_min: val, _idx: min._curr, _curr: min._curr + 1} : {_min: min._min, _idx: min._idx, _curr: min._curr + 1}, {_min: A[0], _idx: 0, _curr: 0}); // returns { _min: -9, _idx: 2, _curr: 6 }
min
giá trị được trả về mà cả vị trí của nó trong Mảng?
Những người khác đã đưa ra một số giải pháp trong đó họ tăng cường Array.prototype
. Tất cả những gì tôi muốn trong câu trả lời này là làm rõ liệu nó nên Math.min.apply( Math, array )
hay Math.min.apply( null, array )
. Vì vậy, bối cảnh nên được sử dụng, Math
hoặc null
?
Khi chuyển null
dưới dạng bối cảnh sang apply
thì bối cảnh sẽ mặc định cho đối tượng toàn cục ( window
đối tượng trong trường hợp trình duyệt). Vượt qua Math
đối tượng làm bối cảnh sẽ là giải pháp chính xác, nhưng nó cũng không bị tổn thương khi vượt qua null
. Đây là một ví dụ khi null
có thể gây rắc rối, khi trang trí Math.max
chức năng:
// decorate Math.max
(function (oldMax) {
Math.max = function () {
this.foo(); // call Math.foo, or at least that's what we want
return oldMax.apply(this, arguments);
};
})(Math.max);
Math.foo = function () {
print("foo");
};
Array.prototype.max = function() {
return Math.max.apply(null, this); // <-- passing null as the context
};
var max = [1, 2, 3].max();
print(max);
Ở trên sẽ ném một ngoại lệ vì this.foo
sẽ được đánh giá là window.foo
, đó là undefined
. Nếu chúng ta thay thế null
với Math
, mọi thứ sẽ làm việc như mong đợi và chuỗi "foo" sẽ được in ra màn hình (Tôi đã thử nghiệm này sử dụng Mozilla Rhino ).
Bạn có thể khá nhiều giả định rằng không ai đã trang trí Math.max
như vậy, vượt qua null
sẽ làm việc mà không có vấn đề.
Foo.staticMethod
và tham khảo this
? Đó sẽ không phải là một sai lầm trong thiết kế của trang trí? (tất nhiên trừ khi họ muốn tham chiếu phạm vi toàn cầu và muốn độc lập với công cụ JavaScript đang được sử dụng, ví dụ Rhino).
Math.max
, thực hiện trên mỗi spec, không sử dụng this
. Nếu ai đó ghi đè lên Math.max
như vậy nó sử dụng this
, thì họ đã làm cho hành vi của nó vi phạm thông số kỹ thuật và bạn nên ném các vật sắc nhọn vào chúng. Bạn không nên mã hóa xung quanh khả năng đó nhiều hơn bạn sẽ mã hóa xung quanh khả năng ai đó đã trao đổi Math.max
và Math.min
cho lulz.
Một cách nữa để làm điều đó:
var arrayMax = Function.prototype.apply.bind(Math.max, null);
Sử dụng:
var max = arrayMax([2, 5, 1]);
Các phương thức Math.min
và Math.max
cả hai đều là các hoạt động đệ quy được thêm vào ngăn xếp cuộc gọi của công cụ JS và rất có thể là sự cố đối với một mảng chứa số lượng lớn các mục
(hơn ~ 10⁷ mục, tùy thuộc vào trình duyệt của người dùng).
Math.max (... Mảng (1000000) .keys ());
Uncaught RangeError: Vượt quá kích thước ngăn xếp cuộc gọi tối đa
Thay vào đó, sử dụng một cái gì đó như vậy:
arr.reduce((max, val) => max > val ? max : val, arr[0])
Hoặc với thời gian chạy tốt hơn:
function maxValue(arr) {
let max = arr[0];
for (let val of arr) {
if (val > max) {
max = val;
}
}
return max;
}
Hoặc để có được cả Min và Max:
function getMinMax(arr) {
return arr.reduce(({min, max}, v) => ({
min: min < v ? min : v,
max: max > v ? max : v,
}), { min: arr[0], max: arr[0] });
}
Hoặc với thời gian chạy tốt hơn *:
function getMinMax(arr) {
let min = arr[0];
let max = arr[0];
let i = arr.length;
while (i--) {
min = arr[i] < min ? arr[i] : min;
max = arr[i] > max ? arr[i] : max;
}
return { min, max };
}
* Đã thử nghiệm với 1.000.000 mục:
Chỉ để tham khảo, thời gian chạy chức năng thứ nhất (trên máy của tôi) là 15,84ms so với chức năng thứ 2 chỉ với 4,32ms.
Điều này có thể phù hợp với mục đích của bạn.
Array.prototype.min = function(comparer) {
if (this.length === 0) return null;
if (this.length === 1) return this[0];
comparer = (comparer || Math.min);
var v = this[0];
for (var i = 1; i < this.length; i++) {
v = comparer(this[i], v);
}
return v;
}
Array.prototype.max = function(comparer) {
if (this.length === 0) return null;
if (this.length === 1) return this[0];
comparer = (comparer || Math.max);
var v = this[0];
for (var i = 1; i < this.length; i++) {
v = comparer(this[i], v);
}
return v;
}
comparer
cho là được gọi trong một số phạm vi cụ thể? Bởi vì nó là tài liệu tham khảo this[index]
đó là undefined
mọi lúc.
Math.xxx
) sẽ chạy trong phạm vi toàn cầu ...
https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Math/max
function getMaxOfArray(numArray) {
return Math.max.apply(null, numArray);
}
var arr = [100, 0, 50];
console.log(getMaxOfArray(arr))
Điều này làm việc cho tôi.
Tôi ngạc nhiên không phải là một chức năng giảm.
var arr = [1, 10, 5, 11, 2]
var b = arr.reduce(function(previous,current){
return previous > current ? previous:current
});
b => 11
arr => [1, 10, 5, 11, 2]
Đối với mảng lớn (~ 10⁷ phần tử) Math.min
vàMath.max
tạo ra RangeError (vượt quá kích thước ngăn xếp cuộc gọi tối đa) trong node.js.
Đối với mảng lớn, giải pháp nhanh & bẩn là:
Array.prototype.min = function() {
var r = this[0];
this.forEach(function(v,i,a){if (v<r) r=v;});
return r;
};
Tôi có cùng một vấn đề, tôi cần phải đạt được các giá trị tối thiểu và tối đa của một mảng và, thật ngạc nhiên, không có các hàm dựng sẵn cho các mảng. Sau khi đọc rất nhiều, tôi quyết định tự mình thử nghiệm các giải pháp "top 3":
Mã kiểm tra là đây:
function GetMaxDISCRETE(A)
{ var MaxX=A[0];
for (var X=0;X<A.length;X++)
if (MaxX<A[X])
MaxX=A[X];
return MaxX;
}
function GetMaxAPPLY(A)
{ return Math.max.apply(null,A);
}
function GetMaxREDUCE(A)
{ return A.reduce(function(p,c)
{ return p>c?p:c;
});
}
Mảng A chứa đầy 100.000 số nguyên ngẫu nhiên, mỗi hàm được thực hiện 10.000 lần trên Mozilla Firefox 28.0 trên máy tính để bàn Pentium 4 2.99GHz intel với Windows Vista. Thời gian tính bằng giây, được lấy bởi hàm Performance.now (). Kết quả là như vậy, với 3 chữ số phân số và độ lệch chuẩn:
Giải pháp GIẢM GIÁ chậm hơn 117% so với giải pháp rời rạc. Giải pháp ỨNG DỤNG kém hơn, chậm hơn 2.118% so với giải pháp rời rạc. Ngoài ra, như Peter quan sát, nó không hoạt động cho các mảng lớn (khoảng hơn 1.000.000 phần tử).
Ngoài ra, để hoàn thành các bài kiểm tra, tôi đã kiểm tra mã rời rạc mở rộng này:
var MaxX=A[0],MinX=A[0];
for (var X=0;X<A.length;X++)
{ if (MaxX<A[X])
MaxX=A[X];
if (MinX>A[X])
MinX=A[X];
}
Thời gian: mean = 0,218s, sd = 0,094
Vì vậy, nó chậm hơn 35% so với giải pháp rời rạc đơn giản, nhưng nó lấy cả giá trị tối đa và tối thiểu cùng một lúc (bất kỳ giải pháp nào khác sẽ mất ít nhất hai lần để lấy chúng). Khi OP cần cả hai giá trị, giải pháp rời rạc sẽ là lựa chọn tốt nhất (thậm chí là hai hàm riêng biệt, một để tính tối đa và một để tính tối thiểu, chúng sẽ vượt trội hơn giải pháp tốt nhất thứ hai, giải pháp GIẢM GIÁ).
Bạn có thể sử dụng chức năng sau ở bất cứ đâu trong dự án của bạn:
function getMin(array){
return Math.min.apply(Math,array);
}
function getMax(array){
return Math.max.apply(Math,array);
}
Và sau đó bạn có thể gọi các hàm truyền qua mảng:
var myArray = [1,2,3,4,5,6,7];
var maximo = getMax(myArray); //return the highest number
Lặp lại, theo dõi khi bạn đi.
var min = null;
var max = null;
for (var i = 0, len = arr.length; i < len; ++i)
{
var elem = arr[i];
if (min === null || min > elem) min = elem;
if (max === null || max < elem) max = elem;
}
alert( "min = " + min + ", max = " + max );
Điều này sẽ để lại min / max null nếu không có phần tử nào trong mảng. Sẽ đặt min và max trong một lượt nếu mảng có bất kỳ phần tử nào.
Bạn cũng có thể mở rộng Array bằng một range
phương thức sử dụng ở trên để cho phép tái sử dụng và cải thiện khả năng đọc. Xem một fiddle làm việc tại http://jsfiddle.net/9C9fU/
Array.prototype.range = function() {
var min = null,
max = null,
i, len;
for (i = 0, len = this.length; i < len; ++i)
{
var elem = this[i];
if (min === null || min > elem) min = elem;
if (max === null || max < elem) max = elem;
}
return { min: min, max: max }
};
Được dùng như
var arr = [3, 9, 22, -7, 44, 18, 7, 9, 15];
var range = arr.range();
console.log(range.min);
console.log(range.max);
range
chức năng này thành một chức năng sẽ là cách tốt nhất để có được cả min và max cùng một lúc IMO - như tôi đã thực hiện với một bản cập nhật cho câu trả lời của mình.
Tôi nghĩ tôi muốn chia sẻ giải pháp đơn giản và dễ hiểu của mình.
Đối với phút:
var arr = [3, 4, 12, 1, 0, 5];
var min = arr[0];
for (var k = 1; k < arr.length; k++) {
if (arr[k] < min) {
min = arr[k];
}
}
console.log("Min is: " + min);
Và tối đa:
var arr = [3, 4, 12, 1, 0, 5];
var max = arr[0];
for (var k = 1; k < arr.length; k++) {
if (arr[k] > max) {
max = arr[k];
}
}
console.log("Max is: " + max);
Đây là một cách để có được giá trị tối đa từ một mảng các đối tượng. Tạo một bản sao (với lát), sau đó sắp xếp bản sao theo thứ tự giảm dần và lấy mục đầu tiên.
var myArray = [
{"ID": 1, "Cost": 200},
{"ID": 2, "Cost": 1000},
{"ID": 3, "Cost": 50},
{"ID": 4, "Cost": 500}
]
maxsort = myArray.slice(0).sort(function(a, b) { return b.ID - a.ID })[0].ID;
Sử dụng Math.max()
hoặcMath.min()
Math.max(10, 20); // 20
Math.min(-10, -20); // -20
Hàm sau sử dụng Function.prototype.apply()
để tìm phần tử tối đa trong một mảng số. getMaxOfArray([1, 2, 3])
tương đương với Math.max(1, 2, 3)
, nhưng bạn có thể sử dụng getMaxOfArray()
trên các mảng được xây dựng theo chương trình với mọi kích thước.
function getMaxOfArray(numArray) {
return Math.max.apply(null, numArray);
}
Hoặc với toán tử trải rộng mới, việc lấy tối đa của một mảng trở nên dễ dàng hơn rất nhiều.
var arr = [1, 2, 3];
var max = Math.max(...arr); // 3
var min = Math.min(...arr); // 1
Giải pháp của ChaosPandion hoạt động nếu bạn đang sử dụng protoype. Nếu không, hãy xem xét điều này:
Array.max = function( array ){
return Math.max.apply( Math, array );
};
Array.min = function( array ){
return Math.min.apply( Math, array );
};
Ở trên sẽ trả về NaN nếu một giá trị mảng không phải là số nguyên vì vậy bạn nên xây dựng một số chức năng để tránh điều đó. Nếu không điều này sẽ làm việc.
Math
đối tượng làm bối cảnh?
Nếu bạn sử dụng thư viện sugar.js , bạn có thể viết Array.min () và Array.max () như bạn đề xuất. Bạn cũng có thể nhận các giá trị tối thiểu và tối đa từ các mảng không phải là số.
tối thiểu (bản đồ, tất cả = sai) Trả về phần tử trong mảng có giá trị thấp nhất. ánh xạ có thể là một hàm ánh xạ giá trị cần kiểm tra hoặc một chuỗi đóng vai trò là một phím tắt. Nếu tất cả là đúng, sẽ trả về tất cả các giá trị tối thiểu trong một mảng.
max (map, all = false) Trả về phần tử trong mảng có giá trị lớn nhất. ánh xạ có thể là một hàm ánh xạ giá trị cần kiểm tra hoặc một chuỗi đóng vai trò là một phím tắt. Nếu tất cả là đúng, sẽ trả về tất cả các giá trị tối đa trong một mảng.
Ví dụ:
[1,2,3].min() == 1
['fee','fo','fum'].min('length') == "fo"
['fee','fo','fum'].min('length', true) == ["fo"]
['fee','fo','fum'].min(function(n) { return n.length; }); == "fo"
[{a:3,a:2}].min(function(n) { return n['a']; }) == {"a":2}
['fee','fo','fum'].max('length', true) == ["fee","fum"]
Các thư viện như Lo-Dash và underscore.js cũng cung cấp các hàm tối thiểu và tối đa mạnh mẽ tương tự:
Ví dụ từ Lo-Dash:
_.max([4, 2, 8, 6]) == 8
var characters = [
{ 'name': 'barney', 'age': 36 },
{ 'name': 'fred', 'age': 40 }
];
_.max(characters, function(chr) { return chr.age; }) == { 'name': 'fred', 'age': 40 }
Thử
let max= a=> a.reduce((m,x)=> m>x ? m:x);
let min= a=> a.reduce((m,x)=> m<x ? m:x);
Đối với Math.min / max (+ áp dụng), chúng tôi gặp lỗi:
Vượt quá kích thước ngăn xếp cuộc gọi tối đa (Chrome 74.0.3729.131)
...
:) vớiMath.max()
như thế này :Math.max(...[2, 5, 16, 1])
. Xem câu trả lời của tôi được thực hiện từ tài liệu MDN .