简体   繁体   中英

find top k elements in array

I have an array in the format:

var series = [[horse,1],[cat,2],[dog,4],[dragon,4],[cow,6]]

In order to find the top 3 elements based on the 2nd parameter I sort the array. So for this purpose I use the code below:

 series.sort( function(a,b) {
        if (a[1] === b[1]) {
            return 0;
    }
    else {
         return (a[1] < b[1]) ? 1 : -1;
    }
});

Which works fine. Then If I want to find the top 3 I can always select [0,2]. However, if the 4th value equals the the 3th then I miss it. In this case if I ask for the top 3 the output should be [[horse,1],[cat,2],[dog,4],[dragon,4] because dragon and dog have equal value (4). So, I wonder is there some library I could use out of the box or some efficient algorithm to return the top 3 values which does not necessarily mean returning top 3 element arrays?

Just build a list:

var top = [];
top.push(series[0]);
top.push(series[1]);
for (var i = 2; i < series.length && series[i][1] == series[2][1]; ++i)
  top.push(series[i]);

To generalize that (a little):

function top(series, k) {
  var top = [];
  for (var i = ; i < k - 1; ++i)
    top.push(series[i]);
  for (; i < series.length && series[k-1][1] == series[i][1]; ++i)
    top.push(series[i]);
  return top;
}
var series = [["horse",1],["cat",2],["dog",4],["dragon",4],["cow",6]]
num = 3;
var arr = [];
for(var i=0; i<series.length; i++)
{
var curr = series[i][1];
var next = series[i][1];
    if(i<num)
    {
     arr.push(series[i]);
    }
    else if(curr==next)
    {
     arr.push(series[i]);
        break;
    }    
}
console.log(arr);

So I would make a second array (length of 3) and loop through the initial array. When The first three items should be automatically added to the array. Then as we loop through the first array and find values higher than the lowest value we remove the lowest value and place the new item in the new array in its proper place.

var series = [[horse,1],[cat,2],[dog,4],[dragon,4],[cow,6]];
function top3(a){
  // Create a new Array to hold the top values
  var top = [a[0], a[1], a[2]]; // Initialize it with the first three items
  for(var i=3;i<a.length;i++){
    /* Find the minimum value and its position */
    var min = top[0][1];
    var min_pos = 0;
    for(var e=1;e<3;e++){
      if(top[e][1]<min){
        min = top[e][1];
        min_post = e;
      }
    }
    /* If larger than the top arrays minimum */
    if( a[i][1] > min ){
      /* remove the top arrays min */
      top.splice(min_pos, 1);
    }
    /* Add the new item into the top array */
    top.push(a[i]);
  }
  /* Now our "top" array has the items with the top 3 values, if you want them sorted use a bubble sort here, if not just return "top" */
  bubbleSortByIndex(a, 1); // Sorts by the second item in an array or arrays
  return top;
};
/*
    Bubble Sort Algorythm adapted from http://en.wikipedia.org/wiki/Bubble_sort
*/
function bubbleSortByIndex(a, i){
  var swapped;
  do {
    swapped = false;
    for(var e=1;e<a.length-1;e++){
      if( a[e-1][i] > A[e][i]){
        swapped = true;
        var temp = a[e-1];
        a[e-1] = a[e];
        a[e] = temp
      }
    }
  } while (swapped);
  return a;
}
top3(series);

This leaves the original array in tact and finds the top three items only, and sorts those. If you wanted the entire original array sorted then just call bubbleSortByIndex(series, 1) and ignore the whole "top3()" function.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM