객체의 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));
시도()a
is 배열,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 |