Nesnenin özellikleri arasında minimum / maksimum değerleri almanın hızlı yolu


94

JavaScript'te şöyle bir nesnem var:

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

Tüm özelliklerin üzerinden geçmek zorunda kalmadan mülkler arasında minimum ve maksimum değeri elde etmenin hızlı bir yolu var mı? çünkü sahip olduğum nesne çok büyük ve her iki saniyede bir min / maks değerini almam gerekiyor. (Nesnenin değerleri değişmeye devam ediyor).


3
@Oleg: Sadece bu göz önüne alındığında JSON olabilir. Yusuf: JSON'u bir nesneye ayrıştırın ve özelliklerini yineleyin.
Felix Kling

@ OlegV.Volkov JSON.parse () kullanıyorum bu Json yapmamalı mı?
Youssef

@Youssef Ayrıştırmadan önce JSON (String değeri) idi. Ayrıştırdıktan sonra bir Object değeridir.
Šime Vidas

2
JSON, nesnelerin dizgi notasyonudur.
JSON'u

1
Yorumlar kastettiğin şeyin bu olduğunu onayladığından, sorunuzdaki JSON -> nesnesini düzeltme özgürlüğünü aldım.
Oleg V. Volkov

Yanıtlar:


19

Tüm döngü olmadan genel durumda maksimum / minimum bulmak için yolu yok n (elemanlar 1 olarak gelen n-1, sen eleman olmadığını bilmek nasıl giderseniz n yerine) değil daha büyük (veya daha küçük akım maks / dak)?

Değerlerin birkaç saniyede bir değiştiğinden bahsettiniz. Tam olarak hangi değerlerin değiştiğini biliyorsanız, önceki maksimum / min değerlerinizle başlayabilir ve yalnızca yenileriyle karşılaştırabilirsiniz, ancak bu durumda bile, değiştirilen değerlerden biri eski maks / min değeriniz ise, tekrar gözden geçirmeniz gerekir.

Başka bir alternatif - yine, yalnızca değişen değerlerin sayısı küçükse - değerleri bir ağaç veya yığın gibi bir yapıda depolamak olabilir ve yeni değerler geldikçe bunları uygun şekilde eklersiniz (veya güncellersiniz). Ancak bunu yapıp yapamayacağınız, sorunuza göre net değil.

Tüm öğeler arasında döngü yaparken belirli bir listenin maksimum / minimum öğesini elde etmek istiyorsanız, aşağıdaki kod parçacığı gibi bir şey kullanabilirsiniz, ancak hepsini gözden geçirmeden bunu yapamazsınız.

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
Bu, bir nesnenin özelliklerinin min / maks değerlerinin nasıl elde edileceğini açıklamaz.
FistOfFury

Liste yerine bir nesne üzerinde yineliyorsunuz. minve maxtanımsızdır. for inBunun yerine bir döngü kullanmak mı istediniz ?
tonix

1
Teşekkürler @tonix, düzeltti.
carlosfigueira

139

Güncelleme: Modern versiyon (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}` );


Orijinal Cevap:

Bunu dene:

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

ve sonra:

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

Canlı demo: http://jsfiddle.net/7GCu7/1/


21
Ayrıca yapabilirimmax = Object.keys(obj).reduce(function(m, k){ return obj[k] > m ? obj[k] : m }, -Infinity);
levi

4
Bunu şimdi de yapabilirsin: Math.max(...arr);
cmac

1
@cmac Bir ES6 sürümü ekledim.
Šime Vidas

@ ŠimeVidas - Math.min & max fonksiyonundaki 3 nokta neyi temsil ediyor? Teşekkürler
AME


12

min ve max yine de girdi dizisi boyunca döngü yapmak zorunda - en büyük veya en küçük öğeyi başka nasıl bulurlar?

Yani sadece hızlı bir for..indöngü gayet iyi çalışacaktır.

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
Bu, IE7 / 8 için harika. Şerefe @Niet the Dark Absol
ojhawkins

Değerlerini almak için dizi boyunca min ve maks döngülerinin olması zorunlu değildir. Diziyi hızlı bir şekilde
sıralayıp

7
@goonerify En hızlı sıralama, O(n log n)doğası gereği bir O(n)kez taramanın olacağından daha yavaş olan ...
Niet the Dark Absol

11

Deneyebilirsin:

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
Açıklama eklendi.
Andrey Kudriavtsev

4

Ayrıca deneyebilirsiniz 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

İşte anahtarı da döndürmenize izin veren ve yalnızca bir döngü yapan bir çözüm. Nesnenin girdilerini (val ile) sıralar ve ardından ilk ve sonuncuyu döndürür.

Ek olarak, mevcut Nesnenin yerini alabilecek sıralı Nesneyi döndürür, böylece gelecekteki sıralamalar daha hızlı olur çünkü zaten yarı sıralı = O (n) 'den daha iyi olacaktır. Nesnelerin ES6'daki sıralarını koruduğuna dikkat etmek önemlidir.

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


Teşekkürler! Değere gitmek için anahtarı tutarken maksimum değeri nasıl elde edeceğimi anlamaya çalışıyordum. Bu yardımcı oldu! :)
010011100101

2

Farklı derinlikteki iç içe geçmiş yapılar için, yani {node: {leaf: 4}, leaf: 1}bu işe yarar (lodash veya alt çizgi kullanarak):

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
Eski bir soruyu cevaplarken, cevabınızın nasıl yardımcı olduğunu açıklamak için bir bağlam eklerseniz, cevabınız diğer StackOverflow kullanıcıları için çok daha faydalı olacaktır, özellikle de zaten kabul edilmiş bir cevabı olan bir soru için. Bakınız: Nasıl iyi bir cevap yazabilirim ?
David Buck

0

Bu benim için çalışıyor:

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); });
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.