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).


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;
}

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/


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];
}

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

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

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);



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));


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;
    }
}

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))

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); });
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.