优化 javascript 代码以在数组中查找 3 个最大的元素及其索引?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11792158/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Optimized javascript code to find 3 largest element and its indexes in array?
提问by tilak
I need more optimized javascript code to find 3 largest element in array. I have tried with this code.
我需要更优化的 javascript 代码才能在数组中找到 3 个最大的元素。我已经尝试过使用此代码。
var maxIndex = new Array();
var maxPoints = new Array();
var scoreByPattern = new Array(93,17,56,91,98,33,9,38,55,78,29,81,60);
function findLargest3(){
maxPoints[0]=0;
maxPoints[1]=0;
maxPoints[2]=0;
for(i=0;i < scoreByPattern.length; i++){
if( scoreByPattern[i] > maxPoints[0]){
maxPoints[0] = scoreByPattern[i];
maxIndex[0]=i;
}
}
for(i=0;i < scoreByPattern.length; i++){
if( scoreByPattern[i] > maxPoints[1] && scoreByPattern[i]< maxPoints[0] ){
maxPoints[1] = scoreByPattern[i];
maxIndex[1]=i;
}
}
for(i=0;i < scoreByPattern.length; i++){
if( scoreByPattern[i] > maxPoints[2] && scoreByPattern[i]< maxPoints[1] ){
maxPoints[2] = scoreByPattern[i];
maxIndex[2]=i;
}
}
alert(scoreByPattern+"/******/"+maxPoints[0]+"/"+maxPoints[1]+"/"+maxPoints[2]);
//alert(maxIndex);
}
how to optimized the above ? (I need indexes of largest numbers)Is any other easy methods to solve the problem ?
如何优化以上内容?(我需要最大数的索引)还有其他简单的方法可以解决这个问题吗?
采纳答案by Rory McCrossan
Sort the array descending, then get the first three elements of it:
将数组降序排序,然后得到它的前三个元素:
var maxPoints = new Array();
var scoreByPattern = new Array(93,17,56,91,98,33,9,38,55,78,29,81,60);
findLargest3();
function findLargest3(){
// sort descending
scoreByPattern.sort(function(a,b) {
if (a < b) { return 1; }
else if (a == b) { return 0; }
else { return -1; }
});
alert(scoreByPattern+"/******/"+scoreByPattern[0]+"/"+scoreByPattern[1]+"/"+scoreByPattern[2]);
}
回答by huysentruitw
Modified version
修改版
I have modified my answer to make it more generic. It searches for the indices of the n largest numbers of elements in the array:
我已经修改了我的答案,使其更通用。它搜索数组中 n 个最大元素的索引:
var scoreByPattern = [93,255,17,56,91,98,33,9,38,55,78,29,81,60];
function findIndicesOfMax(inp, count) {
var outp = [];
for (var i = 0; i < inp.length; i++) {
outp.push(i); // add index to output array
if (outp.length > count) {
outp.sort(function(a, b) { return inp[b] - inp[a]; }); // descending sort the output array
outp.pop(); // remove the last index (index of smallest element in output array)
}
}
return outp;
}
// show original array
console.log(scoreByPattern);
// get indices of 3 greatest elements
var indices = findIndicesOfMax(scoreByPattern, 3);
console.log(indices);
// show 3 greatest scores
for (var i = 0; i < indices.length; i++)
console.log(scoreByPattern[indices[i]]);
Here is a jsFiddle
这是一个jsFiddle
回答by Christoph
Without sorting the huge array: Runs in O(n)
considering the large array. Returns an array of array with [x,y]
where x
is the value and y
the index in the large array.
不排序大数组:在O(n)
考虑大数组时运行。返回一个数组数组,[x,y]
其中x
是y
大数组中的值和索引。
var ar = [3,172,56,91,98,33,9,38,55,78,291,81,60];
console.log(`input is: ${ar}`);
function getMax(ar){
if (ar.length < 3) return ar;
var max = [[ar[0],0],[ar[1],1],[ar[2],2]],
i,j;
for (i = 3;i<ar.length;i++){
for (j = 0;j<max.length;j++){
if (ar[i] > max[j][0]){
max[j] = [ar[i],i];
if (j<2){
max.sort(function(a,b) { return a[0]-b[0]; });
}
break;
}
}
}
return max;
}
result = getMax(ar);
console.log('output [number,index] is:');
console.log(result);
回答by René
The default javascript sort callback won't work well because it sorts in a lexicographical order. 10 would become before 5(because of the 1)
默认的 javascript 排序回调无法正常工作,因为它按字典顺序排序。10 会变成 5 之前(因为 1)
No credit to me but:
不相信我,但是:
my_array.sort(function(a,b) {
return a-b;
});
回答by robert king
Assuming a fairly normal distribution, this should be fairly optimal:
假设一个相当正态分布,这应该是相当理想的:
var max_three, numbers = new Array(93,17,56,91,98,33,9,38,55,78,29,81,60);
max_three = (function (numbers) {
var i, one, two, three;
one = -9999;
two = -9999;
three = -9999;
for (i = 0; i < numbers.length; i += 1) {
num = numbers[i];
if (num > three) {
if (num >= two) {
three = two;
if (num >= one) {
two = one;
one = num;
}
else {
two = num;
}
}
else {
three = num;
}
}
}
return [one, two, three]
}(numbers))
document.write(max_three)???????
98,93,91
98,93,91
回答by Salvador Dali
The best way is to use a combination of sortand slice:
This simple one liner will solve your problem.
这个简单的单衬将解决您的问题。
[1, -5, 2, 8, 17, 0, -2].sort(function(a, b){return b - a}).slice(0, 3)
So if you have an array and want to find N biggest values:
因此,如果您有一个数组并想找到 N 个最大值:
arr.sort(function(a, b){return b - a}).slice(0, n)
And for N smallest values:
对于 N 个最小值:
arr.sort(function(a, b){return a - b}).slice(0, n)
回答by Hunter
Here is an optimized solutionfor your problem without using sort or other complex array method :
这是针对您的问题的优化解决方案,无需使用排序或其他复杂数组方法:
var maxIndex = new Array();
var maxPoints = new Array();
var scoreByPattern = new Array(93,17,56,91,98,33,9,38,55,78,29,81,60);
function findTop3(n) {
for (var i = 0; i < n.length; i ++) {
if (i === 0) {
maxPoints.push(n[i]);
maxIndex.push(i);
} else if (i === 1) {
if (n[i] > maxPoints[0]) {
maxPoints.push(maxPoints[0]);
maxPoints[0] = n[i];
maxIndex.push(maxIndex[0]);
maxIndex[0] = i;
} else {
maxPoints.push(n[i]);
maxIndex.push(i);
}
} else if (i === 2) {
if (n[i] > maxPoints[0]) {
maxPoints.push(maxPoints[0]);
maxPoints[1] = maxPoints[0];
maxPoints[0] = n[i];
maxIndex.push(maxIndex[0]);
maxIndex[1] = maxIndex[0];
maxIndex[0] = i;
} else {
if (n[i] > maxPoints[1]) {
maxPoints.push(maxPoints[1]);
maxPoints[1] = n[i];
maxIndex.push(maxIndex[1]);
maxIndex[1] = i;
} else {
maxPoints.push(n[i]);
maxIndex.push(i);
}
}
} else {
if (n[i] > maxPoints[0]) {
maxPoints[2] = maxPoints[1];
maxPoints[1] = maxPoints[0];
maxPoints[0] = n[i];
maxIndex[2] = maxIndex[1];
maxIndex[1] = maxIndex[0];
maxIndex[0] = i;
} else {
if (n[i] > maxPoints[1]) {
maxPoints[2] = maxPoints[1];
maxPoints[1] = n[i];
maxIndex[2] = maxIndex[1];
maxIndex[1] = i;
} else if(n[i] > maxPoints[2]) {
maxPoints[2] = n[i];
maxIndex[2] = i;
}
}
}
}
}
findTop3(scoreByPattern);
console.log('Top Elements: ', maxPoints);
console.log('With Index: ', maxIndex);
回答by Sani Singh Huttunen
Why don't you just sort it and take the first (or last if sorted in ascending order) three elements.
为什么不直接对它进行排序并取第一个(或最后一个,如果按升序排序)三个元素。
var maxPoints = new Array();
var scoreByPattern = new Array(93,17,56,91,98,33,9,38,55,78,29,81,60);
scoreByPattern.sort();
maxPoints[0] = scoreByPattern[scoreByPattern.length - 1];
maxPoints[1] = scoreByPattern[scoreByPattern.length - 2];
maxPoints[2] = scoreByPattern[scoreByPattern.length - 3];
Edit
If you need the indeces of the largest arrays you can make a copy which you sort and then find the indices in the original array:
编辑
如果您需要最大数组的 indeces,您可以制作一个副本进行排序,然后在原始数组中找到索引:
var scoreByPattern = new Array(93,17,56,91,98,33,9,38,55,78,29,81,60);
// Make a copy of the original array.
var maxPoints = scoreByPattern.slice();
// Sort in descending order.
maxPoints.sort(function(a, b) {
if (a < b) { return 1; }
else if (a == b) { return 0; }
else { return -1; }
});
// Find the indices of the three largest elements in the original array.
var maxPointsIndices = new Array();
maxPointsIndices[0] = scoreByPattern.indexOf(maxPoints[0]);
maxPointsIndices[1] = scoreByPattern.indexOf(maxPoints[1]);
maxPointsIndices[2] = scoreByPattern.indexOf(maxPoints[2]);
Another approach to find the indices without sorting is this:
另一种无需排序即可找到索引的方法是:
var scoreByPattern = new Array(93,17,56,91,98,33,9,38,55,78,29,81,60);
var maxIndices = new Array(Number.MIN_VALUE, Number.MIN_VALUE, Number.MIN_VALUE);
for (var i = 0; i < scoreByPattern.length; i++) {
if (maxIndices[0] < scoreByPattern[i]) {
maxIndices[2] = maxIndices[1];
maxIndices[1] = maxIndices[0];
maxIndices[0] = scoreByPattern[i];
}
else if (maxIndices[1] < scoreByPattern[i]) {
maxIndices[2] = maxIndices[1];
maxIndices[1] = scoreByPattern[i];
}
else if (maxIndices[2] < scoreByPattern[i]) maxIndices[2] = scoreByPattern[i];
}
回答by nbrooks
var maxPoints = [];
var scoreByPattern = [93,17,56,91,98,33,9,38,55,78,29,81,60];
function cloneArray(array) {
return array.map(function(i){ return i; });
}
function max3(array) {
return cloneArray(array).sort(function(a,b) { return b-a; }).slice(0,3);
}
function min3(array) {
return cloneArray(array).sort(function(a,b) { return a-b; }).slice(0,3);
}
var array=scoreByPattern;
alert("Max:"+ max3(array)[0] +' '+max3(array)[1] +' '+max3(array)[2]);
alert("Min:"+ min3(array)[0] +' '+min3(array)[1] +' '+min3(array)[2]);
回答by Ulmasbek rakhmatullaev
function get3TopItems(arr) {
return arr.sort((a, b) => b - a).slice(0, 3);
}