객체의 JavaScript 배열을 최소/최대 값으로 비교
객체 배열을 가지고 있는데 특정 객체 속성에서 이 객체들을 비교하려고 합니다.여기 제 배열이 있습니다.
var myArray = [
    {"ID": 1, "Cost": 200},
    {"ID": 2, "Cost": 1000},
    {"ID": 3, "Cost": 50},
    {"ID": 4, "Cost": 500}
]
저는 구체적으로 "비용"을 제로로 하고 최소값과 최대값을 얻고 싶습니다.비용 값을 잡아 자바스크립트 배열에 밀어 넣은 다음 빠른 자바스크립트 Max/Min을 실행할 수 있다는 것을 깨달았습니다.
그러나 배열 단계를 중간에 무시하고 개체 속성(이 경우 "비용")을 직접 꺼서 이를 더 쉽게 수행할 수 있는 방법이 있습니까?
Array.prototype.reduce() 어레이에서 집계 작업(min, max, avg 등)을 수행하고 단일 결과를 반환하는 것은 다음과 같은 경우에 적합합니다.
myArray.reduce(function(prev, curr) {
    return prev.Cost < curr.Cost ? prev : curr;
});
...또는 ES6 함수 구문을 사용하여 내부 함수를 정의할 수 있습니다.
myArray.reduce((prev, curr) => prev.Cost < curr.Cost ? prev : curr);
귀여운 모습을 보여주고 싶다면 Array 프로토타입에 다음을 첨부하면 됩니다.
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;
 }
한 가지 방법은 모든 요소를 순환시켜 최고/최저 값과 비교하는 것입니다.
(이러한 단순한 작업에서 배열을 생성하고 배열 메서드를 호출하는 것은 과도한 작업입니다.)
 // 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);
사용.Math.min그리고.Math.max:
var myArray = [
    { id: 1, cost: 200},
    { id: 2, cost: 1000},
    { id: 3, cost: 50},
    { id: 4, cost: 500}
]
var min = Math.min(...myArray.map(item => item.cost));
var max = Math.max(...myArray.map(item => item.cost));
console.log("min: " + min);
console.log("max: " + max);배열을 수정해도 상관없는 경우 를 사용합니다.
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));
시도()ais 배열,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);
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);
// TEST
var myArray = [
    {"ID": 1, "Cost": 200},
    {"ID": 2, "Cost": 1000},
    {"ID": 3, "Cost": 50},
    {"ID": 4, "Cost": 500}
]
console.log('Max Cost', max(myArray, 'Cost'));
console.log('Min Cost', min(myArray, 'Cost'));
console.log('Max ID', max(myArray, 'ID'));
console.log('Min ID', min(myArray, 'ID'));Rob 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));
이는 Lodash's를 통해 달성할 수 있습니다.minBy그리고.maxBy기능들.
로다시스minBy그리고.maxBy문서화
_.minBy(array, [iteratee=_.identity])
_.maxBy(array, [iteratee=_.identity])이 메서드는 배열의 각 요소에 대해 호출되는 반복을 허용하여 값의 순위가 매겨지는 기준을 생성합니다.반복은 (value)라는 하나의 인수로 호출됩니다.
해결책
var myArray = [
    {"ID": 1, "Cost": 200},
    {"ID": 2, "Cost": 1000},
    {"ID": 3, "Cost": 50},
    {"ID": 4, "Cost": 500}
]
const minimumCostItem = _.minBy(myArray, "Cost");
console.log("Minimum cost item: ", minimumCostItem);
// Getting the maximum using a functional iteratee
const maximumCostItem = _.maxBy(myArray, function(entry) {
  return entry["Cost"];
});
console.log("Maximum cost item: ", maximumCostItem);<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>Array.prototype.reduce()를 사용하여 비교기 함수를 연결하여 배열에서 최소, 최대값 등의 항목을 결정할 수 있습니다.
var items = [
  { name : 'Apple',  count : 3  },
  { name : 'Banana', count : 10 },
  { name : 'Orange', count : 2  },
  { name : 'Mango',  count : 8  }
];
function findBy(arr, key, comparatorFn) {
  return arr.reduce(function(prev, curr, index, arr) { 
    return comparatorFn.call(arr, prev[key], curr[key]) ? prev : curr; 
  });
}
function minComp(prev, curr) {
  return prev < curr;
}
function maxComp(prev, curr) {
  return prev > curr;
}
document.body.innerHTML  = 'Min: ' + findBy(items, 'count', minComp).name + '<br />';
document.body.innerHTML += 'Max: ' + findBy(items, 'count', maxComp).name;간결하고 현대적인 솔루션을 위해서는 현재 최소값과 최대값을 추적하여 어레이에 대한 연산을 수행할 수 있으므로 어레이를 한 번만 반복할 수 있습니다(최적입니다).
let [min, max] = myArray.reduce(([prevMin,prevMax], {Cost})=>
   [Math.min(prevMin, Cost), Math.max(prevMax, Cost)], [Infinity, -Infinity]);
데모:
var myArray = [
    {"ID": 1, "Cost": 200},
    {"ID": 2, "Cost": 1000},
    {"ID": 3, "Cost": 50},
    {"ID": 4, "Cost": 500}
]
let [min, max] = myArray.reduce(([prevMin,prevMax], {Cost})=>
   [Math.min(prevMin, Cost), Math.max(prevMax, Cost)], [Infinity, -Infinity]);
console.log("Min cost:", min);
console.log("Max cost:", max);이것이 더 나은 해결책입니다.
    var myArray = [
    {"ID": 1, "Cost": 200},
    {"ID": 2, "Cost": 1000},
    {"ID": 3, "Cost": 50},
    {"ID": 4, "Cost": 500}
    ]
    var lowestNumber = myArray[0].Cost;
    var highestNumber = myArray[0].Cost;
    myArray.forEach(function (keyValue, index, myArray) {
      if(index > 0) {
        if(keyValue.Cost < lowestNumber){
          lowestNumber = keyValue.Cost;
        }
        if(keyValue.Cost > highestNumber) {
          highestNumber = keyValue.Cost;
        }
      }
    });
    console.log('lowest number' , lowestNumber);
    console.log('highest Number' , highestNumber);
트리스탄 리드의 답변(+ es6 사용)에 추가하여 콜백을 수락하는 함수를 만들 수 있습니다. 여기에는 적용할 연산자가 포함됩니다.prev그리고.curr:
const compare = (arr, key, callback) => arr.reduce((prev, curr) =>
    (callback(prev[key], curr[key]) ? prev : curr), {})[key];
    // remove `[key]` to return the whole object
그러면 다음을 사용하여 간단히 호출할 수 있습니다.
const costMin = compare(myArray, 'Cost', (a, b) => a < b);
const costMax = compare(myArray, 'Cost', (a, b) => a > b);
우리는 두가지 방법으로 문제를 해결할 수 있습니다. 두 방법 모두 위에서 이미 설명했지만 성능 테스트가 누락되어 하나를 완성했습니다.
1, 네이티브 자바 스크립트 방식
2, 먼저 정렬된 개체를 정렬한 다음 정렬된 개체에서 min max를 쉽게 얻을 수 있습니다.
나는 또한 양쪽 토우 접근법의 성능을 테스트합니다.
실행하고 성능을 테스트할 수도 있습니다.해피코딩(:
//first approach 
var myArray = [
    {"ID": 1, "Cost": 200},
    {"ID": 2, "Cost": 1000},
    {"ID": 3, "Cost": 50},
    {"ID": 4, "Cost": 500}
]
var t1 = performance.now();;
let max=Math.max.apply(Math, myArray.map(i=>i.Cost))
let min=Math.min.apply(Math, myArray.map(i=>i.Cost))
var t2   = performance.now();;
console.log("native fuction took " + (t2 - t1) + " milliseconds.");
console.log("max Val:"+max)
console.log("min Val:"+min)
//  Second approach:
function sortFunc (a, b) {
    return a.Cost - b.Cost
} 
var s1 = performance.now();;
sortedArray=myArray.sort(sortFunc)
var minBySortArray = sortedArray[0],
    maxBySortArray = sortedArray[myArray.length - 1]
    
var s2   = performance.now();;
 console.log("sort funciton took  " + (s2 - s1) + " milliseconds.");  
console.log("max ValBySortArray :"+max)
console.log("min Val BySortArray:"+min)max = totalAVG.reduce(function (a, b) { return Math.max(a, b)}, -Infinity);
min = totalAVG.reduce(function (a, b) {return Math.min(a, b)}, Infinity);
또 하나, 케네벡의 대답과 비슷하지만 모두 한 줄로 늘어놓았습니다.
maxsort = myArray.slice(0).sort(function (a, b) { return b.ID - a.ID })[0].ID; 
내장된 배열 개체를 사용하여 Math.max/Math.min을 대신 사용할 수 있습니다.
var arr = [1,4,2,6,88,22,344];
var max = Math.max.apply(Math, arr);// return 344
var min = Math.min.apply(Math, arr);// return 1
언급URL : https://stackoverflow.com/questions/8864430/compare-javascript-array-of-objects-to-get-min-max
'source' 카테고리의 다른 글
| AttributeError: 'DataFrame' 개체에 'ix' 속성이 없습니다. (0) | 2023.11.05 | 
|---|---|
| MAC phphmyadmin:mariadb로 데이터베이스 서버를 실행하는 방법? (0) | 2023.11.05 | 
| pandas를 만듭니다.사전에서 데이터프레임 (0) | 2023.11.05 | 
| ORA-04036: 인스턴스에서 사용하는 PGA 메모리가 PGA_AGGRATE_LIMIT를 초과합니다. (0) | 2023.11.05 | 
| 오라클 개체 종속성 루프 (0) | 2023.11.05 |