2012-08-05 22 views
5

Me gustaría obtener el valor mínimo de una matriz. Si los datos contienen el valor null, Math.min.apply devuelve 0 para el valor null. Por favor, consulte this JSFiddle example. ¿Cómo puedo obtener el valor mínimo verdadero incluso si existe un valor nulo en la matriz?Math.min.apply devuelve 0 para nulo

Código (igual que en el ejemplo jsFiddle):

var arrayObject= [ {"x": 1, "y": 5}, {"x": 2, "y": 2}, {"x": 3, "y": 9}, {"x": 4, "y": null}, {"x": 5, "y": 12} ]; 

var max = Math.max.apply(Math, arrayObject.map(function(o){return o.y;})); 
var min = Math.min.apply(Math, arrayObject.map(function(o){return o.y;})); 

$("#max").text(max); 
$("#min").text(min); 
+2

No hay JSON en su ejemplo ... corregido. –

+0

La función 'Math.min' realiza (la función interna)' ToNumber() 'en cada elemento de la matriz, que a su vez fuerza los valores a * Number *. La coerción es una mierda, lo sabíamos. ': P' –

+1

@ ŠimeVidas simplemente dejando la propiedad fuera lo haría' indefinido', que a su vez se convierte en 'NaN' que se filtra fácilmente con' .filter (isFinite) ' – Esailija

Respuesta

9

Bueno, el valor numérico de null es 0. Si no desea que null valores a tener en cuenta, hay que filtrarlos:

var values = arrayObject.map(function(o){ 
    return o.y; 
}).filter(function(val) { 
    return val !== null 
}); 

Referencia: Array#filter

+2

O asigne 'null' a' Infinity'. Ahorraría algunos bytes y llamadas a la función 'n' adicionales. – Prinzhorn

+0

@Prinzhorn: Sí, eso también funcionaría ... solo que tienes que mapearlos nuevamente para 'max' a' -Infinity'. Depende de lo que vas a hacer con los datos. –

+0

Como tal: http://stackoverflow.com/a/11817906/139010 –

0
var validArray = $.grep(arrayObject, function(item, _){ 
        return item.y != null; 
       }); 
//That gives a new array without null values for "y" 

Ahora lo hacen ..

var min = Math.min.apply(Math, validArray.map(function(o){return o.y;})); 
+0

El código del OP hizo – Dancrumb

6

Alternativa a la solución de Felix: trate null como + o - inf inity para llamadas mínimas y máximas, respectivamente.

var max = Math.max.apply(Math, arrayObject.map(function(o) { 
    return o.y == null ? -Infinity : o.y; 
})); 
var min = Math.min.apply(Math, arrayObject.map(function(o) { 
    return o.y == null ? Infinity : o.y; 
})); 
+0

Voto. Nunca he visto infinito usado. Yo habría votado dos veces si pudiera. :) –

+1

¿Hay alguna razón para usar la constante en 'Number', no sería el literal' Infinity' (y '-Infinity') más fácil? – Bergi

+0

@Bergi buen punto, gracias. Editado –

4

creo que en lugar de propiedades de asignación, filtrando null valores, y aplicando Math.min/max (como se sugiere en las otras respuestas) la reduce function le ahorrará tiempo y código, mediante la aplicación directa de la lógica:

var arrayObject= [ {"x": 1, "y": 5}, {"x": 2, "y": 2}, {"x": 3, "y": 9}, {"x": 4, "y": null}, {"x": 5, "y": 12} ]; 
var min = var arrayObject.reduce(function(m, o) { 
    return (o.y != null && o.y < m) ? o.y : m; 
}, Infinity); 
var max = var arrayObject.reduce(function(m, o) { 
    return (o.y != null && o.y > m) ? o.y : m; 
}, -Infinity); 
+0

Solución interesante. ¿Cuál es la ganancia de rendimiento en términos de notación O? –

+0

'O (n)' como ninguna otra solución. – Esailija

+0

notación Landau? Ninguna. Pero guarda algunas llamadas a funciones y algo de memoria al no crear las matrices intermedias – Bergi