I have an array of objects and I want to compare those objects on a specific object property. Here's my array:
var myArray = [
{"ID": 1, "Cost": 200},
{"ID": 2, "Cost": 1000},
{"ID": 3, "Cost": 50},
{"ID": 4, "Cost": 500}
]
I'd like to zero in on the "cost" specifically and a get a min and maximum value. I realize I can just grab the cost values and push them off into a javascript array and then run the Fast JavaScript Max/Min.
しかし、途中の配列ステップをバイパスし、オブジェクトのプロパティ (この場合は「コスト」) を直接使用することで、これを行うより簡単な方法はありますか?
ベストアンサー1
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;
}