객체의 속성 중 최소 / 최대 값을 얻는 빠른 방법


94

다음과 같은 자바 스크립트에 개체가 있습니다.

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

속성을 모두 반복하지 않고도 속성 중 최소 및 최대 값을 얻을 수있는 빠른 방법이 있습니까? 내가 가진 물체가 거대하기 때문에 2 초마다 최소 / 최대 값을 얻어야합니다. (객체의 값은 계속 변경됩니다).


3
@Oleg : 음, 이것 만 주어지면 JSON이 될 수 있습니다. Youssef : JSON을 객체로 구문 분석하고 해당 속성을 반복합니다.
Felix Kling

@ OlegV.Volkov JSON.parse ()를 사용하고 있는데 Json으로 만들어야하지 않습니까?
Youssef

@Youssef 파싱하기 전에 JSON (문자열 값)이었습니다. 파싱 ​​후 Object 값입니다.
Šime Vidas 2012-06-21

2
JSON은 객체의 문자열 표기법입니다. 당신이 개체에 JSON을 구문 분석 할 때, 더 이상 JSON 형식 없다
altschuler

1
의견이 귀하가 의미하는 바임을 확인하므로 귀하의 질문에서 JSON-> 객체를 자유롭게 수정했습니다.
Oleg V. Volkov

답변:


19

모든 n 요소 를 반복하지 않고 일반적인 경우 최대 / 최소값을 찾을 수있는 방법은 없습니다 (1에서 n-1로 이동하는 경우 요소 n 이 현재 최대 / 최소)?

값이 몇 초마다 변경된다고 말씀하셨습니다. 어떤 값이 변경되는지 정확히 알고 있다면 이전의 최대 / 최소 값으로 시작하고 새 값과 만 비교할 수 있지만이 경우에도 수정 된 값 중 하나가 이전 최대 / 최소 인 경우 다시 반복해야합니다.

또 다른 대안은-변경되는 값의 수가 적은 경우에만-값을 트리 또는 힙과 같은 구조에 저장하고 새 값이 도착하면 적절하게 삽입 (또는 업데이트)하는 것입니다. 그러나 그렇게 할 수 있는지 여부는 질문에 근거하여 명확하지 않습니다.

모든 요소를 ​​반복하면서 주어진 목록의 최대 / 최소 요소를 얻으려면 아래 스 니펫과 같은 것을 사용할 수 있지만 모든 요소를 ​​거치지 않고는이를 수행 할 수 없습니다.

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
이것은 객체 속성의 최소 / 최대 값을 얻는 방법을 설명하지 않습니다.
FistOfFury

목록이 아니라 객체를 반복하고 있습니다. min그리고 max정의되지 않았습니다. for in대신 루프 를 사용하려고 했습니까 ?
tonix

1
감사합니다 @tonix, 수정했습니다.
carlosfigueira

140

업데이트 : 최신 버전 (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}` );


원래 답변 :

이 시도:

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/


21
또한 할 수max = Object.keys(obj).reduce(function(m, k){ return obj[k] > m ? obj[k] : m }, -Infinity);
레위

4
Math.max(...arr);
지금도이

1
@cmac ES6 버전을 추가했습니다.
Šime Vidas

@ ŠimeVidas-Math.min 및 max 함수의 3 개의 점은 무엇을 나타 냅니까? 감사합니다
AME


12

minmax 어떻게 다른 그들이 가장 큰 또는 작은 요소를 찾을 것입니다 - 어쨌든 입력 배열을 통해 루프가?

따라서 빠른 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
이것은 IE7 / 8에 적합합니다. Cheers @Niet the Dark Absol
ojhawkins

최소값과 최대 값이 배열을 통해 값을 가져 오는 것은 사실이 아닙니다. 배열을 빠르게 정렬하고 해당 결과에 따라 최소값과 최대 값을 선택하는 것이 더 가능합니다.
빠르게 정렬

7
@goonerify 가장 빠른 정렬은입니다 O(n log n).O(n) 단지를 통해 스캔 한 번이 될 것이라고 ...
NIET 어둠 Absol

11

시도해 볼 수 있습니다.

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
설명이 추가되었습니다.
Andrey Kudriavtsev

4

시도해 볼 수도 있습니다. 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

여기에 키도 반환 할 수 있고 하나의 루프 만 수행 할 수있는 솔루션이 있습니다. Object의 항목을 (val 기준) 정렬 한 다음 첫 번째 항목과 마지막 항목을 반환합니다.

추가적으로 기존 Object를 대체 할 수있는 정렬 된 Object를 반환하여 이미 반 정렬 = 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));


감사! 나는 가치와 함께 갈 열쇠를 여전히 유지하면서 최대를 얻는 방법을 알아 내려고 노력했습니다. 이것은 도움이되었습니다! :)
010011100101

2

깊이가 다른 중첩 구조의 경우, 즉 {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;
    }
}

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
이전 질문에 대답 할 때, 특히 이미 승인 된 대답이있는 질문에 대한 대답이 어떻게 도움이되는지 설명하는 컨텍스트를 포함하면 다른 StackOverflow 사용자에게 대답이 훨씬 더 유용 할 것입니다. 참조 : 좋은 답변을 작성하는 방법 .
David Buck

0

이것은 나를 위해 작동합니다.

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); });
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.