0

I am trying to display only top 3 records in a key value pair using jquery. How can I find index for each item?

My trails fiddle

var _map = {
  'severity-normal': 0,
  'severity-minimal': 0,
  'severity-moderate': 0,
  'severity-severe': 0,
  'severity-highly-severe': 0
};

$.each(_map, function(key, value) {
  //alert(index + ': ' + value); 

    $('body').append('Key: ' + key + ' Value: ' + value + '<br />')

});
Kurkula
  • 6,673
  • 23
  • 99
  • 170
  • What do you mean by "index"? You seem to be getting both the keys and values fine. Also objects don't have order to their properties like arrays do. – Spencer Wieczorek Jul 06 '16 at 23:19
  • I am trying to display top 3 key value pairs only and not all. I am trying for for(var I=0;i – Kurkula Jul 06 '16 at 23:20
  • Top 3, as in, the ones with the highest values? And shouldn't you be trying to find the keys for each item in top 3, not the index? (they don't have indices after all) – Andros Rex Jul 06 '16 at 23:20
  • is there any option to get top n records in dictionary? I am looking for any values but top 3 in dictionary. – Kurkula Jul 06 '16 at 23:22
  • @Chandana I don't think you understand, objects in JavaScript are un-ordered. They [cannot be guaranteed](http://stackoverflow.com/questions/5525795/does-javascript-guarantee-object-property-order) to be simply in the order you defined them. There is no such thing as the "top 3", you might want to use a `Map` object or an array. Yes some browsers will preserved the order, but you can't be dependent on that. – Spencer Wieczorek Jul 06 '16 at 23:36

2 Answers2

1

Ok, I think I got what you meant...

O(NlogN) solution, if there are N items in _map

var _map = {
  'severity-normal': 0,
  'severity-minimal': 0,
  'severity-moderate': 0,
  'severity-severe': 0,
  'severity-highly-severe': 0
};

var list = [];

$.each(_map, function(key, value) {
    list.push({key:key, value:value});
});

list.sort(function(a,b) { return b.value - a.value; } );

for(var i=0; i<3 && i<list.length; i++) {
    alert(i + ': ' + list[i].value);
}

O(K*N) solution, if you want to get the top K items and there are N items

var _map = {
  'severity-normal': 0,
  'severity-minimal': 0,
  'severity-moderate': 0,
  'severity-severe': 0,
  'severity-highly-severe': 0
};

function getTopElements(map, k) {
    var lastMaximum = Infinity, currentMaximum;
    var outputList = [];

    while(outputList.length < k) {
        currentMaximum = -Infinity;

        for(key in map) {
            if(map[key] > currentMaximum && map[key] < lastMaximum) {
                currentMaximum = map[key];
            }
        }

        for(key in map) {
            if(map[key] == currentMaximum) {
                outputList.push(map[key]);
            }
            if(outputList.length >= k) break;
        }

        lastMaximum = currentMaximum;
    }

    return outputList;
}

var list = getTopElements(map,3);

for(var i=0; i<list.length; i++) {
    alert(i + ': ' + list[i].value);
}
Andros Rex
  • 372
  • 1
  • 7
  • The sort is pointless and `.append()` isn't a valid function, it needs to be `.push()`. Also how does this help? – Spencer Wieczorek Jul 06 '16 at 23:28
  • @Spencer Wieczorek Yeah, I spaced out while typing append(). Thanks for the correction. The sort isn't pointless, though - Chandana wants the top 3 records, so they have to be sorted in descending order first. But now that I think about it, this isn't an optimal solution... let me fix it. – Andros Rex Jul 06 '16 at 23:45
  • All the values are `0`, so the sort will not change the order. The OP never stated how they need to be sorted. – Spencer Wieczorek Jul 06 '16 at 23:48
  • @Spencer Wieczorek They just have to have values assigned to them, so he must have felt lazy and put zeroes everywhere. It's logical to assume that they won't always have zeroes. And he may have not stated how he wants them to be sorted, but "top 3" usually means the 3 with the highest values assigned to them. Besides, it's easy to reverse their order or just traverse them in the opposite direction. – Andros Rex Jul 06 '16 at 23:55
1

You should use Object.keys which returns an array of the Objects properties, you can then loop through the values with that array:

var _mapIndexes = Object.keys(_map);

for (var i=0; i<_mapIndexes.length; i++) {

  // i = the index of the _map key
  // _mapIndexes[i] = the index in the _map object
  // _map[_mapIndexes[i]] = the object

  if (i > 2) break;
  $('body').append('Key: '+_mapIndexes[i]+' Value: '+_map[_mapIndexes[i]]+'<br />')
  top3.push(_map[_mapIndexes[i]])
}

Here is a link to the updated jsFiddle

If you need to sort the objects in order of value. You can use Object.keys() with .sort():

var _sortedMap = Object.keys(_map).sort(function(a,b){return _map[a]-_map[b]})

See the updated jsFiddle

Sinan Guclu
  • 1,010
  • 6
  • 16