У меня есть такой объект в javascript:
{ "a":4, "b":0.5 , "c":0.35, "d":5 }
Есть ли быстрый способ получить минимальное и максимальное значение среди свойств без необходимости перебирать их все? потому что объект, который у меня есть, огромен, и мне нужно получать минимальное / максимальное значение каждые две секунды. (Значения объекта постоянно меняются).
javascript
jquery
Юсеф
источник
источник
Ответы:
Невозможно найти максимум / минимум в общем случае без перебора всех n элементов (если вы перейдете от 1 к n-1, как узнать, не больше ли (или меньше) элемент n, чем ток макс / мин)?
Вы упомянули, что значения меняются каждые пару секунд. Если вы точно знаете, какие значения меняются, вы можете начать с ваших предыдущих значений max / min и сравнивать только с новыми, но даже в этом случае, если одно из измененных значений было вашим старым max / min, вы можете нужно повторить их снова.
Другой альтернативой - опять же, только если количество изменяющихся значений невелико - было бы хранить значения в такой структуре, как дерево или куча, и по мере поступления новых значений вы должны были бы вставить (или обновить) их соответствующим образом. Но можете ли вы это сделать, неясно, исходя из вашего вопроса.
Если вы хотите получить максимальный / минимальный элемент данного списка, перебирая все элементы, вы можете использовать что-то вроде приведенного ниже фрагмента, но вы не сможете сделать это, не пройдя все из них.
var list = { "a":4, "b":0.5 , "c":0.35, "d":5 }; var keys = Object.keys(list); var min = list[keys[0]]; // ignoring case of empty list for conciseness var max = list[keys[0]]; var i; for (i = 1; i < keys.length; i++) { var value = list[keys[i]]; if (value < min) min = value; if (value > max) max = value; }
источник
min
иmax
не определены. Вы хотелиfor in
вместо этого использовать цикл?Обновление: современная версия (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}` );
Оригинальный ответ:
Попробуй это:
let obj = { a: 4, b: 0.5 , c: 0.35, d: 5 }; 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/
источник
max = Object.keys(obj).reduce(function(m, k){ return obj[k] > m ? obj[k] : m }, -Infinity);
Math.max(...arr);
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]; }
источник
O(n log n)
, которая по своей сути медленнее, чем приO(n)
однократном сканировании ...Вы можете попробовать:
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
источник
// 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
источник
Вы также можете попробовать
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);
источник
Используя библиотеку lodash, вы можете писать короче
_({ "a":4, "b":0.5 , "c":0.35, "d":5 }).values().max();
источник
Вот решение, которое также позволяет вернуть ключ и выполняет только один цикл. Он сортирует записи объекта (по значению), а затем возвращает первую и последнюю.
Кроме того, он возвращает отсортированный объект, который может заменить существующий объект, так что будущие сортировки будут быстрее, потому что он уже будет частично отсортирован = лучше, чем 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));
источник
Для вложенных структур разной глубины, т.е.
{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; } }
источник
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))
источник
Это работает для меня:
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); });
источник