2012-06-21 9 views
52

mam obiektu w javascript takiego:szybki sposób uzyskać min/max wartości między właściwościami obiektu

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

Czy istnieje szybki sposób, aby uzyskać minimalną i maksymalną wartość spośród właściwości bez konieczności przeglądasz je wszystkie? ponieważ obiekt, który mam, jest ogromny i potrzebuję uzyskać wartość min/max co dwie sekundy. (Wartości obiektu ciągle się zmieniają).

+2

Masz obiekt, a nie JSON. –

+3

@Oleg: Cóż, biorąc pod uwagę tylko to, może to być JSON. Youssef: Przetwórz JSON na obiekt i sprawdź jego właściwości. –

+0

@ OlegV.Volkov Używam JSON.parse() nie powinno to zrobić Json? – Youssef

Odpowiedz

13

Nie ma sposobu, aby znaleźć maksymalną/minimalną w ogólnym przypadku bez zapętlenie poprzez wszystkie n elementów (jeśli go od 1 do n-1, to skąd wiesz, czy element n nie jest większy (lub mniejszy) niż aktualny maks./Min)?

Wspomniał Pan, że wartości zmieniają się co kilka sekund. Jeśli wiesz dokładnie, które wartości się zmieniają, możesz zacząć od poprzednich wartości maksymalnych/minimalnych i porównać je tylko z nowymi, ale nawet w tym przypadku, jeśli jedną z wartości, które zostały zmodyfikowane było twoje stare maks./Min, możesz Muszę ponownie przechodzić przez nie.

Inna alternatywa - ponownie, tylko jeśli liczba wartości, które ulegną zmianie, jest mała - będzie przechowywanie wartości w strukturze, takiej jak drzewo lub sterty, a jako nowe wartości zostaną wstawione (lub zaktualizowane)) odpowiednio. Ale czy możesz to zrobić, nie jest jasne w oparciu o twoje pytanie.

+7

+1 za użycie innej struktury danych – fet

8

min i max muszą mimo to przechodzić przez macierz wejściową - jak inaczej mogą znaleźć największy lub najmniejszy element?

Po prostu szybka pętla for..in będzie działać dobrze.

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

To jest świetne dla IE7/8. Pozdrawiam @Niet the Dark Absol – ojhawkins

+0

Nie musi to być prawda, że ​​min i max przechodzą przez tablicę, aby uzyskać ich wartości. Bardziej prawdopodobne jest to, że szybko indeksują tablicę i wybierają wartości min i maksimum na podstawie tego wyniku. – goonerify

+5

@goonerify Najszybszym sortowaniem jest 'O (n log n)', który jest z natury wolniejszy niż 'O (n)', który właśnie skanuje kiedyś będzie ... –

75

Spróbuj tego:

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

, a następnie:

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

żywo demo:http://jsfiddle.net/7GCu7/1/


Aktualizacja: Nowoczesna wersja (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

Można również wykonać polecenie "max = Object.keys (obj) .reduce (function (m, k) {return obj [k]> m? obj [k] : m}, -Infinity); ' – levi

+2

Może to również zrobić teraz:' Math.max (... arr); ' – cmac

+1

@ cmac Dodałem wersję ES6. –

2

Dla zagnieżdżonych struktur o różnej głębokości, tj {node: {leaf: 4}, leaf: 1}, to będzie działać (przy użyciu lodash lub podkreślenie):

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

Działa to dla mnie:

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

Proszę podać wyjaśnienie dotyczące kodu. – Boiethios

+0

Dodano wyjaśnienie. –

Powiązane problemy