J'ai un tableau d'objets et je veux comparer ces objets sur une propriété d'objet spécifique. Voici mon tableau:
var myArray = [
{"ID": 1, "Cost": 200},
{"ID": 2, "Cost": 1000},
{"ID": 3, "Cost": 50},
{"ID": 4, "Cost": 500}
]
Je voudrais me concentrer sur le "coût" en particulier et obtenir une valeur minimale et maximale. Je me rends compte que je peux simplement saisir les valeurs de coût et les transférer dans un tableau javascript, puis exécuter le Fast JavaScript Max/Min .
Cependant, y a-t-il un moyen plus simple de faire cela en contournant l’étape du tableau au milieu et en supprimant directement les propriétés de l’objet (dans ce cas, "Coût")?
Dans ce cas, le moyen le plus rapide consiste à parcourir tous les éléments et à le comparer à la valeur la plus élevée/la plus faible, jusqu'à présent.
(Créer un tableau, invoquer des méthodes de tableau est une opération excessive pour cette opération simple).
// 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);
La réduction est bonne pour des choses comme celle-ci: effectuer des opérations d'agrégation (comme min, max, avg, etc.) sur un tableau d'objets et renvoyer un seul résultat:
myArray.reduce(function(prev, curr) {
return prev.Cost < curr.Cost ? prev : curr;
});
... ou vous pouvez définir cette fonction interne avec la syntaxe de la fonction ES6:
(prev, curr) => prev.Cost < curr.Cost ? prev : curr
Si vous voulez être mignon, vous pouvez attacher ceci à array:
Array.prototype.hasMin = function(attrib) {
return this.reduce(function(prev, curr){
return prev[attrib] < curr[attrib] ? prev : curr;
});
}
Maintenant, vous pouvez juste dire:
myArray.hasMin('ID') // result: {"ID": 1, "Cost": 200}
myArray.hasMin('Cost') // result: {"ID": 3, "Cost": 50}
Utilisez sort
, si vous ne vous souciez pas du tableau en cours de modification.
myArray.sort(function (a, b) {
return a.Cost - b.Cost
})
var min = myArray[0],
max = myArray[myArray.length - 1]
Je pense que la réponse de Rob W est vraiment le bon (+1), mais juste pour le plaisir: si vous vouliez être "intelligent", vous pourriez fait quelque chose comme ça:
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"));
ou si vous aviez une structure profondément imbriquée, vous pourriez devenir un peu plus fonctionnel et procéder comme suit:
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; }));
Celles-ci pourraient facilement être classées dans des formes plus utiles/spécifiques.
Utilisez les fonctions Math
et extrayez les valeurs de votre choix avec map
.
Voici le 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
MISE À JOUR:
Si vous souhaitez utiliser ES6:
var min = Math.min.apply(null, myArray.map(item => item.Cost)),
max = Math.max.apply(null, myArray.map(item => item.Cost));
En utilisant Array.prototype.reduce () , vous pouvez intégrer des fonctions de comparaison pour déterminer l'élément min, max, etc. d'un tableau.
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;
Ceci est une meilleure solution
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);
En ajoutant à la réponse de Tristan Reid (+ en utilisant es6), vous pouvez créer une fonction qui accepte un rappel, qui contiendra l'opérateur que vous souhaitez appliquer à prev
et 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
Ensuite, vous pouvez simplement l'appeler en utilisant:
const costMin = compare(myArray, 'Cost', (a, b) => a < b);
const costMax = compare(myArray, 'Cost', (a, b) => a > b);
Ceci peut être réalisé avec les fonctions minBy
et maxBy
de lodash.
Documentation de Lodash minBy
et maxBy
_.minBy(array, [iteratee=_.identity])
_.maxBy(array, [iteratee=_.identity])
Ces méthodes acceptent un iteratee qui est appelé pour chaque élément du tableau afin de générer le critère de classement de la valeur. L'itéré est appelé avec un argument: (valeur).
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>