2012-08-05 12 views
5

Vorrei ottenere il valore minimo da un array. Se il dato contiene il valore null, Math.min.apply restituisce 0 per il valore null. Si prega di vedere this JSFiddle example. Come posso ottenere il valore minimo vero anche se esiste un valore null nell'array?Math.min.apply restituisce 0 per null

codice (come nel JSFiddle esempio):

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

Non c'è nessun JSON nel tuo esempio ... corretto. –

+0

La funzione 'Math.min' esegue (la funzione interna)' ToNumber() 'su ogni elemento dell'array, che a sua volta costringe i valori a * Numero *. La coercizione fa schifo, lo sapevamo. ': P' –

+1

@ ŠimeVidas semplicemente lasciando la proprietà fuori sarebbe" non definito ", che a sua volta si trasforma in' NaN' che è facilmente filtrato con '.filter (isFinite)' – Esailija

risposta

9

Ebbene, il valore numerico per null è 0. Se non si desidera null valori da prendere in considerazione, è necessario filtrare fuori:

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

Riferimento: Array#filter

+2

Oppure mappa 'null' su' Infinito'. Salverebbe alcuni byte e chiamate di funzione 'n' aggiuntive. – Prinzhorn

+0

@ Prinzhorn: Sì, funzionerebbe anche ... solo che devi mapparli di nuovo per 'max' su' -Infinity'. Dipende da cosa farai con i dati. –

+0

Mi piace così: 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" 

Ora fare ..

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

Il codice OP ha fatto – Dancrumb

6

Alternativa alla soluzione di Felix: trattamento null come + o - inf unità per chiamate min e max, rispettivamente.

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. Non ho mai visto l'infinito messo in uso. Avrei votato due volte se potessi. :) –

+1

C'è un motivo per usare la costante su 'Numero', il letterale' Infinito' (e '-Infinity') non sarebbe più semplice? – Bergi

+0

@Bergi buon punto, grazie. Modificato. –

4

Penso invece di proprietà di mappatura, filtrando null valori, e applicando Math.min/max (come suggerito dalle altre risposte) la reduce function vi farà risparmiare un po 'di tempo e il codice, applicando direttamente la logica:

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

Soluzione interessante. Qual è il guadagno in termini di prestazioni in termini di notazione O? –

+0

'O (n)' non diversamente da qualsiasi altra soluzione. – Esailija

+0

Notazione Landau? Nessuna. Ma si salvano alcune chiamate di funzione e un po 'di memoria non creando gli array intermedi – Bergi