Tengo un objeto en javascript como este:
{ "a":4, "b":0.5 , "c":0.35, "d":5 }
¿Existe una manera rápida de obtener el valor mínimo y máximo entre las propiedades sin tener que recorrerlas todas? porque el objeto que tengo es enorme y necesito obtener el valor mínimo / máximo cada dos segundos. (Los valores del objeto siguen cambiando).
javascript
jquery
Youssef
fuente
fuente
Respuestas:
No hay forma de encontrar el máximo / mínimo en el caso general sin recorrer todos los n elementos (si pasa de 1 a n-1, ¿cómo sabe si el elemento n no es más grande (o más pequeño) que el corriente max / min)?
Mencionaste que los valores cambian cada dos segundos. Si sabe exactamente qué valores cambian, puede comenzar con sus valores máximos / mínimos anteriores y comparar solo con los nuevos, pero incluso en este caso, si uno de los valores que se modificaron era su antiguo máximo / mínimo, puede Necesito recorrerlos nuevamente.
Otra alternativa, nuevamente, solo si la cantidad de valores que cambian es pequeña, sería almacenar los valores en una estructura como un árbol o un montón, y cuando lleguen los nuevos valores, los insertaría (o actualizaría) de manera apropiada. Pero si puede hacerlo, no está claro según su pregunta.
Si desea obtener el elemento máximo / mínimo de una lista determinada mientras recorre todos los elementos, puede usar algo como el fragmento a continuación, pero no podrá hacerlo sin pasar por todos ellos.
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; }
fuente
min
ymax
no están definidos. ¿Querías usar unfor in
bucle en su lugar?Actualización: versión moderna (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}` );
Respuesta original:
Prueba esto:
let obj = { a: 4, b: 0.5 , c: 0.35, d: 5 }; var arr = Object.keys( obj ).map(function ( key ) { return obj[key]; });
y entonces:
var min = Math.min.apply( null, arr ); var max = Math.max.apply( null, arr );
Demostración en vivo: http://jsfiddle.net/7GCu7/1/
fuente
max = Object.keys(obj).reduce(function(m, k){ return obj[k] > m ? obj[k] : m }, -Infinity);
Math.max(...arr);
min
ymax
tienen que recorrer la matriz de entrada de todos modos, ¿de qué otra manera encontrarían el elemento más grande o más pequeño?Así que solo un
for..in
bucle rápido funcionará bien.var min = Infinity, max = -Infinity, x; for( x in input) { if( input[x] < min) min = input[x]; if( input[x] > max) max = input[x]; }
fuente
O(n log n)
, que es inherentemente más lento que elO(n)
que solo escanear una vez sería ...Tu podrías intentar:
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
fuente
// 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
fuente
También puedes probar con
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);
fuente
Usando la biblioteca lodash puede escribir más corto
_({ "a":4, "b":0.5 , "c":0.35, "d":5 }).values().max();
fuente
Aquí hay una solución que le permite devolver la clave también y solo hace un bucle. Ordena las entradas del Objeto (por val) y luego devuelve la primera y la última.
Además, devuelve el Objeto ordenado que puede reemplazar el Objeto existente para que las clasificaciones futuras sean más rápidas porque ya estará semi ordenado = mejor que O (n). Es importante tener en cuenta que los objetos conservan su orden en 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));
fuente
Para estructuras anidadas de diferente profundidad, es decir
{node: {leaf: 4}, leaf: 1}
, esto funcionará (usando lodash o subrayado):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; } }
fuente
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))
fuente
Esto funciona para mi:
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); });
fuente