How to return key of object with higher value in Javascript?

Asked

Viewed 1,864 times

8

Let’s say I have the following object:

var obj = {"frutas": 50, "vegetais": 100, "carnes": 150 };

How could I return the key of the highest value item? Example:

obj.maxKey(); // "carnes"

I tested some functions that deal with arrays, but apparently they do not work with objects in the pattern key: value, example:

Math.max.apply(null, meuArrayAqui);

So, how I could return the key of the highest value item?

  • Accepts the use of frameworks?

  • @Fernando jQuery yes, but not third-party plugins.

  • uhm! I was thinking in that, but now that I realize that in your case is not an array but an object, and this only works for array? Or it can be with array?

3 answers

6


There is no native function for this, so you will need to check all values to find the largest:

var obj = {"frutas": 50, "vegetais": 100, "carnes": 150 };
var maior = -Infinity;
var chave;
for(var prop in obj) {
    // ignorar propriedades herdadas
    if(obj.hasOwnProperty(prop)) { 
         if(obj[prop] > maior) {
             maior = obj[prop];
             chave = prop;
         }
    }
}
alert(chave);

That’s the principle. Of course, for real use, it’s better to wrap it in a function. Depending on the desired use, one can still do some optimizations.

  • Great answer, I chose it as correct because I do not need third party libraries and because I do not persist the values of the object in case of reuse of the function.

3

The simplest way seems to me to be with a loop even, but if you seek a more functional alternative, it can be done as follows:

  • Get all object keys by using Object.keys;
  • Sort them in descending order of value (you need to use a custom function for this);
  • Take the first element.

Example:

var obj = {"frutas": 50, "vegetais": 100, "carnes": 150 };

var maior = Object.keys(obj).sort(function(a,b) {
                return obj[a] > obj[b] ? -1 :
                       obj[b] > obj[a] ? 1 : 0;
            })[0];

document.querySelector("body").innerHTML += "<p>" + maior + "</p>";

  • 1

    I took a test and found that this is quite slow. Slower than using jQuery for the loop.

  • 1

    @bfavaretto It does not surprise me, given what ordination is n*log(n), while the rest are just n... If AP hadn’t explicitly said it didn’t want third-party frameworks, I would suggest _.max, which makes it possible to establish an arbitrary criterion for max without having to perform unnecessary operations. Anyway, a simple loop should be faster than any more sophisticated alternative.

  • 1

    Yeah, the underscore was the first thing I thought. Maybe in ES7 (!) there is one Object.values, then you could do something cleaner (which is a great quality of your solution).

2

Using the each of jQuery and traversing through all objects, can do as follows:

function getKeyOfMaxObjValue(obj){
  // Variável que armazenará a maior key.
  var key;
  // Variável auxiliar para checar os valores
  var value = 0;
  $.each(obj, function(idx, val){
    // Se o valor atual da iteração é maior que o auxiliar
    if(val > value){
      // Atualiza o valor da variável auxiliar
      value = val;
      // Atribue a nova key
      key = idx;
    }
  });
  return key;
}
  • Solution very clean, but when I use the function then with an object of different values, it keeps returning the result of the first object I used.

  • @mgibsonbr I tested it on that flash drive, but I ended up replacing it with the solution marked "correct" because of the problem mentioned above. You can change the function there for this to reproduce what I commented.

  • 1

    @mgibsonbr Actually, I re-tested here and the error did not reproduce again, funny that it was only change the function that it had disappeared the first time. Anyway, I’ll remove the comments.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.