Cara cepat untuk mendapatkan nilai min / max di antara properti objek

94

Saya memiliki objek dalam javascript seperti ini:

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

Apakah ada cara cepat untuk mendapatkan nilai minimum dan maksimum di antara properti tanpa harus mengulang semuanya? karena objek yang saya miliki sangat besar dan saya perlu mendapatkan nilai min / max setiap dua detik. (Nilai objek terus berubah).

Youssef
sumber
3
@ Oleg: Yah, mengingat hanya ini, bisa jadi itu adalah JSON. Youssef: Parsing JSON menjadi sebuah objek dan lakukan iterasi terhadap propertinya.
Felix Kling
@ OlegV.Volkov Saya menggunakan JSON.parse () bukankah seharusnya itu menjadikannya Json?
Youssef
@Youssef Itu adalah JSON (yang merupakan nilai String) sebelum parsing. Ini adalah nilai Object setelah parsing.
Šime Vidas
2
JSON adalah notasi string objek. Saat Anda mengurai JSON menjadi objek, objek tersebut tidak lagi dalam format JSON
altschuler
1
Saya mengambil kebebasan untuk memperbaiki JSON -> objek dalam pertanyaan Anda, karena komentar mengonfirmasi bahwa itu yang Anda maksud.
Oleg V. Volkov

Jawaban:

19

Tidak ada cara untuk menemukan maksimum / minimum dalam kasus umum tanpa mengulang melalui semua n elemen (jika Anda beralih dari, 1 ke n-1, bagaimana Anda mengetahui apakah elemen n tidak lebih besar (atau lebih kecil) dari maks / menit saat ini)?

Anda menyebutkan bahwa nilainya berubah setiap beberapa detik. Jika Anda tahu persis nilai mana yang berubah, Anda bisa mulai dengan nilai maks / min sebelumnya, dan hanya membandingkan dengan yang baru, tetapi bahkan dalam kasus ini, jika salah satu nilai yang diubah adalah maks / menit lama Anda, Anda dapat perlu mengulanginya lagi.

Alternatif lain - sekali lagi, hanya jika jumlah nilai yang berubah kecil - akan menyimpan nilai dalam struktur seperti pohon atau heap, dan saat nilai baru tiba, Anda akan memasukkan (atau memperbaruinya) dengan tepat. Tetapi apakah Anda dapat melakukannya tidak jelas berdasarkan pertanyaan Anda.

Jika Anda ingin mendapatkan elemen maksimum / minimum dari daftar yang diberikan saat melakukan perulangan melalui semua elemen, Anda dapat menggunakan sesuatu seperti cuplikan di bawah ini, tetapi Anda tidak akan dapat melakukannya tanpa melalui semuanya

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;
}
carlosfigueira.dll
sumber
2
Ini tidak menjelaskan cara mendapatkan nilai min / max dari properti suatu objek.
FistOfFury
Anda mengulang suatu objek, bukan daftar. mindan maxtidak ditentukan. Apakah Anda bermaksud menggunakan for inloop?
tonix
1
Terima kasih @tonix, perbaiki.
carlosfigueira
139

Pembaruan: Versi modern (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}` );


Jawaban Asli:

Coba ini:

let obj = { a: 4, b: 0.5 , c: 0.35, d: 5 };
var arr = Object.keys( obj ).map(function ( key ) { return obj[key]; });

lalu:

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

Demo langsung: http://jsfiddle.net/7GCu7/1/

Šime Vidas
sumber
21
Bisa juga melakukanmax = Object.keys(obj).reduce(function(m, k){ return obj[k] > m ? obj[k] : m }, -Infinity);
levi
4
Bisa juga melakukan ini sekarang: Math.max(...arr);
cmac
1
@cmac Saya telah menambahkan versi ES6.
Šime Vidas
@ ŠimeVidas - apa yang diwakili oleh 3 titik pada fungsi Math.min & max? Terima kasih
AME
12

mindan maxharus mengulang melalui larik input - bagaimana lagi mereka akan menemukan elemen terbesar atau terkecil?

Jadi for..inloop cepat saja sudah cukup.

var min = Infinity, max = -Infinity, x;
for( x in input) {
    if( input[x] < min) min = input[x];
    if( input[x] > max) max = input[x];
}
Niet the Dark Absol
sumber
1
Ini bagus untuk IE7 / 8. Cheers @Niet the Dark Absol
ojhawkins
Ini belum tentu benar bahwa min dan max melakukan perulangan melalui array untuk mendapatkan nilainya. Lebih mungkin bahwa mereka quicksort array dan memilih nilai min dan max berdasarkan hasil itu
goonerify
7
@goonerify Jenis tercepat adalah O(n log n), yang secara inheren lebih lambat daripada O(n)yang hanya memindai sekali akan ...
Niet the Dark Absol
11

Kamu bisa mencoba:

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
Dave Kalu
sumber
5
// 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
Andrey Kudriavtsev
sumber
1
Penjelasan ditambahkan.
Andrey Kudriavtsev
4

Anda juga bisa mencoba dengan 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);

Neel Rathod
sumber
3

Dengan menggunakan perpustakaan lodash, Anda dapat menulis lebih pendek

_({ "a":4, "b":0.5 , "c":0.35, "d":5 }).values().max();
Sergey Zhigalov
sumber
3

Berikut adalah solusi yang memungkinkan Anda mengembalikan kunci dan hanya melakukan satu putaran. Ini mengurutkan entri Objek (menurut val) dan kemudian mengembalikan yang pertama dan terakhir.

Selain itu, ini mengembalikan Objek yang diurutkan yang dapat menggantikan Objek yang ada sehingga pengurutan di masa mendatang akan lebih cepat karena sudah menjadi semi-sort = lebih baik daripada O (n). Penting untuk diperhatikan bahwa Objek mempertahankan urutannya di 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));

JBallin
sumber
Terima kasih! Saya mencoba mencari cara untuk mendapatkan nilai maksimal sambil tetap mempertahankan kunci untuk mengikuti nilainya. Ini membantu! :)
010011100101
2

Untuk struktur bertingkat dengan kedalaman berbeda, yaitu {node: {leaf: 4}, leaf: 1}, ini akan berfungsi (menggunakan lodash atau garis bawah):

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;
    }
}
pengguna4815162342
sumber
2
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))
pengguna12723650
sumber
3
Saat menjawab pertanyaan lama, jawaban Anda akan jauh lebih berguna bagi pengguna StackOverflow lainnya jika Anda menyertakan beberapa konteks untuk menjelaskan bagaimana jawaban Anda membantu, terutama untuk pertanyaan yang sudah memiliki jawaban yang diterima. Lihat: Bagaimana cara menulis jawaban yang bagus .
David Buck
0

Ini bekerja untuk saya:

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); });
jaydip jadhav
sumber