私は次のようなJavaScriptのオブジェクトを持っています:
{ "a":4, "b":0.5 , "c":0.35, "d":5 }
すべてをループすることなく、プロパティの最小値と最大値をすばやく取得する方法はありますか?私が持っているオブジェクトは巨大で、2秒ごとに最小/最大値を取得する必要があるためです。(オブジェクトの値は変化し続けます)。
私は次のようなJavaScriptのオブジェクトを持っています:
{ "a":4, "b":0.5 , "c":0.35, "d":5 }
すべてをループすることなく、プロパティの最小値と最大値をすばやく取得する方法はありますか?私が持っているオブジェクトは巨大で、2秒ごとに最小/最大値を取得する必要があるためです。(オブジェクトの値は変化し続けます)。
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}` );
これを試して:
let obj = { a: 4, b: 0.5 , c: 0.35, d: 5 };
var arr = Object.keys( obj ).map(function ( key ) { return obj[key]; });
その後:
var min = Math.min.apply( null, arr );
var max = Math.max.apply( null, arr );
ライブデモ: http: //jsfiddle.net/7GCu7/1/
一般的なケースでは、 n個の要素すべてをループせずに最大/最小を見つける方法はありません(1からn-1に変更した場合、要素nが現在の最大/分)?
値は数秒ごとに変わるとおっしゃいました。どの値が変更されるかが正確にわかっている場合は、以前の最大/最小値から始めて、新しい値とのみ比較できますが、この場合でも、変更された値の1つが古い最大/最小である場合はそれらを再度ループする必要があります。
もう1つの方法は、変更する値の数が少ない場合にのみ、ツリーやヒープなどの構造に値を格納し、新しい値が到着したら適切に挿入(または更新)することです。しかし、あなたがそれを行うことができるかどうかは、あなたの質問に基づいて明確ではありません。
すべての要素をループしながら特定のリストの最大/最小要素を取得したい場合は、以下のスニペットのようなものを使用できますが、すべてを通過しないとそれを行うことはできません
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;
}
あなたは試すことができます:
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
min
とにかく入力配列をループする必要がありmax
ます-他にどのようにして最大または最小の要素を見つけるでしょうか?
したがって、クイックfor..in
ループだけで問題なく動作します。
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. 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
で試すこともできます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);
lodashライブラリを使用すると、より短く書くことができます
_({ "a":4, "b":0.5 , "c":0.35, "d":5 }).values().max();
これは、キーも返すことができ、ループを1つだけ実行できるソリューションです。オブジェクトのエントリを(valで)並べ替えてから、最初と最後のエントリを返します。
さらに、既存のオブジェクトを置き換えることができるソートされたオブジェクトを返します。これにより、すでにセミソートされているため、将来のソートが高速になります= O(n)よりも優れています。オブジェクトは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));
異なる深さのネストされた構造の場合、つまり{node: {leaf: 4}, leaf: 1}
、これは機能します(lodashまたはアンダースコアを使用):
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;
}
}
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))
関数を使用できますreduce()
。
例:
let obj = { "a": 4, "b": 0.5, "c": 0.35, "d": 5 }
let max = Object.entries(obj).reduce((max, entry) => entry[1] >= max[1] ? entry : max, [0, -Infinity])
let min = Object.entries(obj).reduce((min, entry) => entry[1] <= min[1] ? entry : min, [0, +Infinity])
console.log(max) // ["d", 5]
console.log(min) // ["c", 0.35]
// 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 ]
これは私のために働きます:
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); });
obj.prototype.getMaxinObjArr = function (arr,propName) {
var _arr = arr.map(obj => obj[propName]);
return Math.max(..._arr);
}
最大値と最小値のキーを取得するには
var list = { "a":4, "b":0.5 , "c":0.35, "d":5 };
var keys = Object.keys(list);
var min = keys[0]; // ignoring case of empty list for conciseness
var max = keys[0];
var i;
for (i = 1; i < keys.length; i++) {
var value = keys[i];
if (list[value] < list[min]) min = value;
if (list[value] > list[max]) max = value;
}
console.log(min, '-----', max)