# How can I compare values from multiple objects?

I want to compare values from objects that I keep in an array.

I know that I can create new arrays with values from each object but I'm trying to find some way to do it without creating them.

Consider we have such situation:

``````soldiers[first, second, third]
first{name: John, shooting: 95, combat: 50, tactic: 88}
second{name: Arnold, shooting: 97, combat: 72, tactic: 68}
third{name: William, shooting: 87, combat: 86, tactic: 97}
``````

I'd like to select the best soldier from the provided above - but I can't create one rating (i.e. average).

There will be some conditions that soldier must fill - for example: at least 60 points in combat (no matter if every other property is 100).

So I'm trying to find way to compare multiple properties and return name of just one soldier.

I'll appreciate every tip. Thanks!

On Best Solutions

I have made you an exmaple with comments. Let me know if this pushes you in the right direction or if you need any other help.

``````const soldiers = [{
name: "John",
shooting: 95,
combat: 50,
tactic: 88
},
{
name: "Arnold",
shooting: 97,
combat: 72,
tactic: 68
},
{
name: "William",
shooting: 87,
combat: 86,
tactic: 97
}
];

const filteredSoldiers = soldiers
.filter(soldier => soldier.combat > 60) // Find every soldier where combat is higher than 60
.map(soldier => {
return {
name: soldier.name,
average: (soldier.combat + soldier.tactic + soldier.shooting) / 3
};
// map will return an array with the filtered soldiers, and we put their average and their name in there
})
.sort((a, b) => b.average - a.average);
// Lastly we sort them high to low by their average score

console.log(
filteredSoldiers.length > 0 ? filteredSoldiers[0].name : 'No soldiers with combat score higher thn 60'
);``````

jsfiddle

In the filter condition you can of course add more checks.

On

You need to got through all items and select best value;

Note that some soldiers can have similar values, that's why `values.name` is array

``````let a = {
name: "John", shooting: 95, combat: 50, tactic: 88
};
let b = {
name: "Arnold", shooting: 97, combat: 72, tactic: 68
};
let c = {
name: "William", shooting: 87, combat: 86, tactic: 97
};
let soldiers = [a, b, c];
let values = {
shooting: {
name: [],
score: 0
},
combat: {
name: [],
score: 0
},
tactic: {
name: [],
score: 0
}
};

soldiers.map((item) => {
['shooting', 'combat', 'tactic'].forEach(name => {
if (item[name] > values[name].score) {
values[name].name = [item.name];
values[name].score = item[name];
} else if (item[name] === values[name].score) {
values[name].name.push(item.name);
}
});
});

console.log(values);
``````
On

Considering you have mentioned that not all skills are equally important, I would suggest weighted total as a cumulative metric:

Following demo implements that approach:

``````//src array
const soldiers = [
{name: 'John', shooting: 95, combat: 50, tactic: 88},
{name: 'Arnold', shooting: 97, combat: 72, tactic: 68},
{name: 'William', shooting: 87, combat: 86, tactic: 97}
];
//cumulative score
const cumulative = soldier => {
//weight for each skill
const weights = {shooting: 1, combat: 1.5, tactic: 1.8};
//extract skill properties into skills-object
({name, ...skills} = soldier);
//iterate through skills and calculate weighted total
return Object.entries(skills).reduce((score,item) => score += item[1]*weights[item[0]],0);
};
//best performer
const bestPerformer = soldiers.reduce((best, soldier) => cummulative(best) > cumulative(soldier) ? best : soldier, soldiers[0]);

console.log(bestPerformer);``````