[javascript] 최소 / 최대를 얻기 위해 자바 스크립트 객체 배열 비교

객체 배열이 있고 특정 객체 속성에서 해당 객체를 비교하고 싶습니다. 내 배열은 다음과 같습니다.

var myArray = [
    {"ID": 1, "Cost": 200},
    {"ID": 2, "Cost": 1000},
    {"ID": 3, "Cost": 50},
    {"ID": 4, "Cost": 500}
]

구체적으로 “비용”에 초점을 맞추고 최소값과 최대 값을 얻고 싶습니다. 비용 값을 가져 와서 자바 스크립트 배열로 밀어 넣은 다음 Fast JavaScript Max / Min 을 실행할 수 있다는 것을 알고 있습니다 .

그러나 중간에있는 배열 단계를 건너 뛰고 개체 속성 (이 경우 “비용”)을 직접 해제하여이를 수행하는 더 쉬운 방법이 있습니까?



답변

이 경우 가장 빠른 방법은 모든 요소를 ​​반복하여 지금까지의 최고 / 최저 값과 비교하는 것입니다.

(배열을 만들고 배열 메서드를 호출하는 것은이 간단한 작업에 과잉입니다).

 // There's no real number bigger than plus Infinity
var lowest = Number.POSITIVE_INFINITY;
var highest = Number.NEGATIVE_INFINITY;
var tmp;
for (var i=myArray.length-1; i>=0; i--) {
    tmp = myArray[i].Cost;
    if (tmp < lowest) lowest = tmp;
    if (tmp > highest) highest = tmp;
}
console.log(highest, lowest);


답변

감소는 다음과 같은 작업에 유용합니다. 객체 배열에 대해 집계 연산 (최소, 최대, 평균 등)을 수행하고 단일 결과를 반환합니다.

myArray.reduce(function(prev, curr) {
    return prev.Cost < curr.Cost ? prev : curr;
});

… 또는 ES6 함수 구문으로 내부 함수를 정의 할 수 있습니다.

(prev, curr) => prev.Cost < curr.Cost ? prev : curr

귀엽고 싶다면 이것을 배열에 붙일 수 있습니다.

Array.prototype.hasMin = function(attrib) {
    return (this.length && this.reduce(function(prev, curr){ 
        return prev[attrib] < curr[attrib] ? prev : curr; 
    })) || null;
 }

이제 다음과 같이 말할 수 있습니다.

myArray.hasMin('ID')  // result:  {"ID": 1, "Cost": 200}
myArray.hasMin('Cost')    // result: {"ID": 3, "Cost": 50}
myEmptyArray.hasMin('ID')   // result: null

이것을 사용하려는 경우 모든 상황에 대한 전체 검사가있는 것은 아닙니다. 기본 유형의 배열을 전달하면 실패합니다. 존재하지 않는 속성을 확인하거나 모든 개체에 해당 속성이 포함되어 있지 않은 경우 마지막 요소를 가져옵니다. 이 버전은 좀 더 부피가 크지 만 다음과 같은 검사가 있습니다.

Array.prototype.hasMin = function(attrib) {
    const checker = (o, i) => typeof(o) === 'object' && o[i]
    return (this.length && this.reduce(function(prev, curr){
        const prevOk = checker(prev, attrib);
        const currOk = checker(curr, attrib);
        if (!prevOk && !currOk) return {};
        if (!prevOk) return curr;
        if (!currOk) return prev;
        return prev[attrib] < curr[attrib] ? prev : curr; 
    })) || null;
 }


답변

sort수정되는 배열에 대해 신경 쓰지 않는 경우를 사용하십시오 .

myArray.sort(function (a, b) {
    return a.Cost - b.Cost
})

var min = myArray[0],
    max = myArray[myArray.length - 1]


답변

Math함수를 사용 하고 원하는 값을 map.

다음은 jsbin입니다.

https://jsbin.com/necosu/1/edit?js,console

var myArray = [{
    "ID": 1,
    "Cost": 200
  }, {
    "ID": 2,
    "Cost": 1000
  }, {
    "ID": 3,
    "Cost": 50
  }, {
    "ID": 4,
    "Cost": 500
  }],

  min = Math.min.apply(null, myArray.map(function(item) {
    return item.Cost;
  })),
  max = Math.max.apply(null, myArray.map(function(item) {
    return item.Cost;
  }));

console.log('min', min);//50
console.log('max', max);//1000

최신 정보:

ES6를 사용하려는 경우 :

var min = Math.min.apply(null, myArray.map(item => item.Cost)),
    max = Math.max.apply(null, myArray.map(item => item.Cost));


답변

내 생각 롭 W의 대답은 정말 올바른 (+1)이지만, 단지 재미를 위해 : 당신은 “영리”이 원한다면, 당신은 할 수 같은 것을 할 :

var myArray = 
[
    {"ID": 1, "Cost": 200},
    {"ID": 2, "Cost": 1000},
    {"ID": 3, "Cost": 50},
    {"ID": 4, "Cost": 500}
]

function finder(cmp, arr, attr) {
    var val = arr[0][attr];
    for(var i=1;i<arr.length;i++) {
        val = cmp(val, arr[i][attr])
    }
    return val;
}

alert(finder(Math.max, myArray, "Cost"));
alert(finder(Math.min, myArray, "Cost"));

또는 깊이 중첩 된 구조가있는 경우 좀 더 기능적으로 다음을 수행 할 수 있습니다.

var myArray = 
[
    {"ID": 1, "Cost": { "Wholesale":200, Retail: 250 }},
    {"ID": 2, "Cost": { "Wholesale":1000, Retail: 1010 }},
    {"ID": 3, "Cost": { "Wholesale":50, Retail: 300 }},
    {"ID": 4, "Cost": { "Wholesale":500, Retail: 1050 }}
]

function finder(cmp, arr, getter) {
    var val = getter(arr[0]);
    for(var i=1;i<arr.length;i++) {
        val = cmp(val, getter(arr[i]))
    }
    return val;
}

alert(finder(Math.max, myArray, function(x) { return x.Cost.Wholesale; }));
alert(finder(Math.min, myArray, function(x) { return x.Cost.Retail; }));

이것들은 더 유용하고 특정한 형태로 쉽게 커리 될 수 있습니다.


답변

최대

Math.max.apply(Math, myArray.map(a => a.Cost));

분 동안

Math.min.apply(Math, myArray.map(a => a.Cost));


답변

Try ( a배열, f비교할 필드 임)

let max= (a,f)=> a.reduce((m,x)=> m[f]>x[f] ? m:x);
let min= (a,f)=> a.reduce((m,x)=> m[f]<x[f] ? m:x);