Mam taki obiekt w javascript:
{ "a":4, "b":0.5 , "c":0.35, "d":5 }
Czy istnieje szybki sposób na uzyskanie minimalnej i maksymalnej wartości między właściwościami bez konieczności przeglądania ich wszystkich w pętli? ponieważ obiekt, który mam, jest ogromny i muszę uzyskiwać wartość min / max co dwie sekundy. (Wartości obiektu ciągle się zmieniają).
javascript
jquery
Youssef
źródło
źródło
Odpowiedzi:
W ogólnym przypadku nie ma sposobu, aby znaleźć maksimum / minimum bez przechodzenia przez wszystkie n elementów (jeśli przejdziesz od, 1 do n-1, skąd wiesz, czy element n nie jest większy (lub mniejszy) niż prąd max / 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ównywać tylko z nowymi, ale nawet w tym przypadku, jeśli jedną z modyfikowanych wartości była Twoja stara wartość maksymalna / minimalna, możesz trzeba je ponownie przejrzeć.
Inną alternatywą - znowu, tylko jeśli liczba zmienianych wartości jest mała - byłoby przechowywanie wartości w strukturze, takiej jak drzewo lub sterta, a gdy nowe wartości nadejdą, należy je odpowiednio wstawić (lub zaktualizować). Ale czy możesz to zrobić, nie jest jasne na podstawie twojego pytania.
Jeśli chcesz uzyskać maksymalny / minimalny element danej listy podczas przeglądania wszystkich elementów, możesz użyć czegoś takiego jak poniższy fragment, ale nie będziesz w stanie tego zrobić bez przejrzenia ich wszystkich
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; }
źródło
min
imax
są niezdefiniowane. Czyfor in
zamiast tego chciałeś użyć pętli?Aktualizacja: wersja nowoczesna (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}` );
Oryginalna odpowiedź:
Spróbuj tego:
let obj = { a: 4, b: 0.5 , c: 0.35, d: 5 }; var arr = Object.keys( obj ).map(function ( key ) { return obj[key]; });
i wtedy:
var min = Math.min.apply( null, arr ); var max = Math.max.apply( null, arr );
Demo na żywo: http://jsfiddle.net/7GCu7/1/
źródło
max = Object.keys(obj).reduce(function(m, k){ return obj[k] > m ? obj[k] : m }, -Infinity);
Math.max(...arr);
min
imax
mimo wszystko muszą przepętać tablicę wejściową - jak inaczej mogliby znaleźć największy lub najmniejszy element?Więc po prostu szybka
for..in
pętla 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]; }
źródło
O(n log n)
, że jest z natury wolniejsze niż to,O(n)
że samo skanowanie raz byłoby ...Możesz spróbować:
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
źródło
// 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
źródło
Możesz także spróbować
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);
źródło
Korzystając z biblioteki lodash możesz pisać krócej
_({ "a":4, "b":0.5 , "c":0.35, "d":5 }).values().max();
źródło
Oto rozwiązanie, które pozwala również zwrócić klucz i wykonuje tylko jedną pętlę. Sortuje wpisy Obiektu (według wartości), a następnie zwraca pierwszy i ostatni.
Dodatkowo zwraca posortowany obiekt, który może zastąpić istniejący obiekt, dzięki czemu przyszłe sortowanie będzie szybsze, ponieważ będzie już częściowo posortowane = lepiej niż O (n). Należy zauważyć, że obiekty zachowują swoją kolejność w 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));
źródło
W przypadku struktur zagnieżdżonych o różnej głębokości
{node: {leaf: 4}, leaf: 1}
to zadziała (używając lodash lub podkreślenia):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; } }
źródło
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))
źródło
To działa 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); });
źródło
// Sorted let Sorted = Object.entries({ "a":4, "b":0.5 , "c":0.35, "d":5 }).sort((prev, next) => prev[1] - next[1]) >> [ [ 'c', 0.35 ], [ 'b', 0.5 ], [ 'a', 4 ], [ 'd', 5 ] ] //Min: Sorted.shift() >> [ 'c', 0.35 ] // Max: Sorted.pop() >> [ 'd', 5 ]
źródło