Fast way to get the min/max values among properties of object

I have an object in javascript like this:

{ "a":4, "b":0.5 , "c":0.35, "d":5 }

Is there a fast way to get the minimum and maximum value among the properties without having to loop through them all? because the object I have is huge and I need to get the min/max value every two seconds. (The values of the object keeps changing).

Answers:

Answer

There's no way to find the maximum / minimum in the general case without looping through all the n elements (if you go from, 1 to n-1, how do you know whether the element n isn't larger (or smaller) than the current max/min)?

You mentioned that the values change every couple of seconds. If you know exactly which values change, you can start with your previous max/min values, and only compare with the new ones, but even in this case, if one of the values which were modified was your old max/min, you may need to loop through them again.

Another alternative - again, only if the number of values which change are small - would be to store the values in a structure such as a tree or a heap, and as the new values arrive you'd insert (or update) them appropriately. But whether you can do that is not clear based on your question.

Answer

Try this:

var arr = Object.keys( obj ).map(function ( key ) { return obj[key]; });

and then:

var min = Math.min.apply( null, arr );
var max = Math.max.apply( null, arr );

Live demo: http://jsfiddle.net/7GCu7/1/


Update: Modern version (ES6+)

let obj = { a: 4, b: 0.5 , c: 0.35, d: 5 };

let arr = Object.values(obj);
let min = Math.min(...arr);
let max = Math.max(...arr);

console.log( `Min value: ${min}, max value: ${max}` );

Answer

min and max have to loop through the input array anyway - how else would they find the biggest or smallest element?

So just a quick for..in loop will work just fine.

var min = Infinity, max = -Infinity, x;
for( x in input) {
    if( input[x] < min) min = input[x];
    if( input[x] > max) max = input[x];
}
Answer

You could try:

const obj = { a: 4, b: 0.5 , c: 0.35, d: 5 };
const max = Math.max.apply(null, Object.values(obj));
console.log(max) // 5
Answer
// 1. iterate through object values and get them
// 2. sort that array of values ascending or descending and take first, 
//    which is min or max accordingly
let obj = { 'a': 4, 'b': 0.5, 'c': 0.35, 'd': 5 }
let min = Object.values(obj).sort((prev, next) => prev - next)[0] // 0.35
let max = Object.values(obj).sort((prev, next) => next - prev)[0] // 5
Answer

Using the lodash library you can write shorter

_({ "a":4, "b":0.5 , "c":0.35, "d":5 }).values().max();
Answer

For nested structures of different depth, i.e. {node: {leaf: 4}, leaf: 1}, this will work (using lodash or underscore):

function getMaxValue(d){
    if(typeof d === "number") {
        return d;
    } else if(typeof d === "object") {
        return _.max(_.map(_.keys(d), function(key) {
            return getMaxValue(d[key]);
        }));
    } else {
        return false;
    }
}
Answer

Here's a solution that allows you to return the key as well and only does one loop. It sorts the Object's entries (by val) and then returns the first and last one.

Additionally, it returns the sorted Object which can replace the existing Object so that future sorts will be faster because it will already be semi-sorted = better than O(n). It's important to note that Objects retain their order in ES6.

const maxMinVal = (obj) => {
  const sortedEntriesByVal = Object.entries(obj).sort(([, v1], [, v2]) => v1 - v2);

  return {
    min: sortedEntriesByVal[0],
    max: sortedEntriesByVal[sortedEntriesByVal.length - 1],
    sortedObjByVal: sortedEntriesByVal.reduce((r, [k, v]) => ({ ...r, [k]: v }), {}),
  };
};

const obj = {
  a: 4, b: 0.5, c: 0.35, d: 5
};

console.log(maxMinVal(obj));

Answer

You can also try with Object.values

const points = { Neel: 100, Veer: 89, Shubham: 78, Vikash: 67 };

const vals = Object.values(points);
const max = Math.max(...vals);
const min = Math.min(...vals);
console.log(max);
console.log(min);

Answer

This works for me:

var object = { a: 4, b: 0.5 , c: 0.35, d: 5 };
// Take all value from the object into list
var valueList = $.map(object,function(v){
     return v;
});
var max = valueList.reduce(function(a, b) { return Math.max(a, b); });
var min = valueList.reduce(function(a, b) { return Math.min(a, b); });
Answer
var newObj = { a: 4, b: 0.5 , c: 0.35, d: 5 };
var maxValue = Math.max(...Object.values(newObj))
var minValue = Math.min(...Object.values(newObj))

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.