2012-06-21 12 views
52

que tiene un objeto en Javascript como esto:manera rápida de conseguir los valores mín/máx entre las propiedades de objeto

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

¿Hay una manera rápida de conseguir el mínimo y el valor máximo entre las propiedades sin tener que recorrer todos ellos? porque el objeto que tengo es enorme y necesito obtener el valor mínimo/máximo cada dos segundos. (Los valores del objeto cambian constantemente).

+2

Tienes objeto, no JSON. –

+3

@Oleg: Bueno, dado solo esto, podría ser JSON. Youssef: analiza el JSON en un objeto e itera sobre sus propiedades. –

+0

@ OlegV.Volkov Estoy usando JSON.parse() ¿no debería hacerlo Json? – Youssef

Respuesta

13

No hay manera de encontrar el máximo/mínimo en el caso general, sin bucle a través de todos los n elementos (si se pasa de 1 a n-1, ¿cómo saber si el elemento n no es más grande (o más pequeño) que el máximo/mínimo actual)?

Mencionó que los valores cambian cada dos segundos. Si sabe exactamente qué valores cambian, puede comenzar con sus valores máximos/mínimos anteriores, y solo compararlos con los nuevos, pero incluso en este caso, si uno de los valores que se modificaron fue el anterior máximo/mínimo, puede necesita recorrerlos de nuevo.

Otra alternativa, una vez más, solo si el número de valores que cambian son pequeños, sería almacenar los valores en una estructura como un árbol o un montón, y cuando lleguen los nuevos valores insertarías (o actualizarías) ellos apropiadamente. Pero si puede hacer eso no está claro en función de su pregunta.

+7

+1 para usar una estructura de datos diferente – fet

8

min y max tienen que recorrer la matriz de entrada de todos modos, ¿de qué otro modo encontrarían el elemento más grande o más pequeño?

Así que solo un rápido for..in lazo 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]; 
} 
+0

Esto es genial para IE7/8. Cheers @Niet the Dark Absol – ojhawkins

+0

No es necesariamente cierto que el mínimo y el máximo recorren la matriz para obtener sus valores. Es más factible que ordenen la matriz y seleccionen los valores mínimos y máximos en función de ese resultado. – goonerify

+5

@goonerify La clasificación más rápida es 'O (n log n)', que es inherentemente más lenta que ''O (n)' que acaba de escanear una vez sería ... –

75

Prueba esto:

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

y luego:

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

Demostración en directo:http://jsfiddle.net/7GCu7/1/


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

+14

También se puede hacer 'max = Object.keys (obj) .reduce (función (m, k) {return obj [k]> m? obj [k] : m}, -Infinity); ' – levi

+2

También puede hacer esto ahora:' Math.max (... arr); ' – cmac

+1

@cmac He agregado una versión ES6. –

2

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

Esto funciona para mí:

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); }); 
2
// 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 
+1

Agregue algunas explicaciones sobre su código. – Boiethios

+0

Explicación agregada. –

Cuestiones relacionadas