Подтвердить что ты не робот

Быстрый способ получить значения min/max среди свойств объекта

У меня есть объект в javascript:

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

Есть ли быстрый способ получить минимальное и максимальное значение среди свойств без необходимости их прокрутки? потому что объект, который у меня есть, огромен, и мне нужно получить значение min/max каждые две секунды. (Значения объекта продолжают меняться).

4b9b3361

Ответ 1

Невозможно найти максимум/минимум в общем случае без прокрутки всех элементов n (если вы переходите от 1 до n-1, откуда вы знаете, будет ли элемент n не больше (или меньше), чем ток max/min)?

Вы упомянули, что значения меняются каждые две секунды. Если вы точно знаете, какие значения меняются, вы можете начать с ваших предыдущих значений max/min и сравнивать только с новыми, но даже в этом случае, если одно из значений, которые были изменены, было вашим старым max/min, вы можете необходимо снова пропустить их.

Другая альтернатива - опять же, только если количество значений, которые изменяются невелики, - это хранить значения в структуре, такой как дерево или куча, и по мере поступления новых значений вы должны вставлять (или обновлять) их надлежащим образом. Но можете ли вы сделать это, неясно, на основании вашего вопроса.

Ответ 2

Попробуй это:

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

а потом:

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

Демо-версия: http://jsfiddle.net/7GCu7/1/


Обновление: современная версия (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}' );

Ответ 3

min и max должны все равно проходить через входной массив - как иначе они найдут самый большой или самый маленький элемент?

Итак, просто быстрый цикл for..in будет работать нормально.

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

Ответ 4

Вы можете попробовать:

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

Ответ 5

// 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

Ответ 6

Используя библиотеку lodash, вы можете писать короче

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

Ответ 7

Для вложенных структур разной глубины, т.е. {node: {leaf: 4}, leaf: 1}, это будет работать (используя lodash или подчеркивание):

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;
    }
}

Ответ 8

Здесь решение, которое позволяет вам также вернуть ключ и делает только один цикл. Он сортирует записи объекта (по значению), а затем возвращает первый и последний.

Кроме того, он возвращает отсортированный объект, который может заменить существующий объект, так что будущие сортировки будут быстрее, потому что он уже будет частично отсортирован = лучше, чем O (n). Важно отметить, что объекты сохраняют свой порядок в 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));

Ответ 9

Это работает для меня:

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); });

Ответ 10

Вы также можете попробовать с 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);