Reputation: 182
So I have this array of pilots :
var pilots = [
{
id: 10,
name: "Poe Dameron",
years: 14,
},
{
id: 2,
name: "Temmin 'Snap' Wexley",
years: 30,
},
{
id: 41,
name: "Tallissan Lintra",
years: 16,
},
{
id: 99,
name: "Ello Asty",
years: 22,
}
];
And I want to print the most experienced pilot. By using reduce() I can print the most experienced one. But this reduce function will print the last pilot with most experience. In the above array the reduce works perfectly:
var mostExpPilot = pilots.reduce(function (oldest, pilot) {
return (oldest.years || 0) > pilot.years ? oldest : pilot;
}, {});
console.log(mostExpPilot); // Prints { id: 2, name: 'Temmin \'Snap\' Wexley', years: 30 }
If we have 2 or more pilots with the same experience and I want to print both occurrences. For example we have the below array where there are two pilots with the same years of experience. The reduce function that is implemented it prints only the last pilot.
var pilots = [
{
id: 10,
name: "Poe Dameron",
years: 14,
},
{
id: 2,
name: "Temmin 'Snap' Wexley",
years: 30,
},
{
id: 41,
name: "Tallissan Lintra",
years: 30,
},
{
id: 99,
name: "Ello Asty",
years: 22,
}
];
//find the most experienced pilot
var mostExpPilot = pilots.reduce(function (oldest, pilot) {
return (oldest.years || 0) > pilot.years ? oldest : pilot;
}, {});
console.log(mostExpPilot); // prints { id: 41, name: 'Tallissan Lintra', years: 30 }
Can I do it with reduce() ? If yes, could you please let me know? If no, how can I do that? Thanks.**
Upvotes: 1
Views: 127
Reputation: 12561
The following gets it all down to two lines but takes more passes than reduce (which takes just one). Nevertheless if the sample size will always be small the readability may be worth it:
const mostYearsExperience = Math.max.apply({}, pilots.map(p => p.years));
const mostExperiencedPilots = pilots.filter(p => p.years === mostYearsExperience);
Upvotes: 1
Reputation: 939
var mostExpPilot = pilots.reduce(function (oldest, pilot) {
return oldest[0].years < pilot.years ? [pilot] : (oldest[0].years == pilot.years ? [...oldest, pilot] : oldest);
}, [pilots[0]]);
console.log(mostExpPilot);
Upvotes: 1
Reputation: 1075019
If we have 2 or more pilots with the same experience and I want to print both occurrences.
To do that, you'll need to return an array. If you're going to return an array sometimes, it's best to return an array always (even if it will have only one entry in it).
You'd do it by returning an array with just the current pilot if that pilot has more experience than the previously-known pilot, adding the current pilot to the array if they have the same experience, or keeping the previously-known pilot otherwise:
var pilots = [
{
id: 10,
name: "Poe Dameron",
years: 14,
},
{
id: 2,
name: "Temmin 'Snap' Wexley",
years: 30,
},
{
id: 41,
name: "Tallissan Lintra",
years: 30,
},
{
id: 99,
name: "Ello Asty",
years: 22,
}
];
// Find the most experienced pilots
var mostExpPilot = pilots.reduce(function(most, pilot) {
var mostYears = most[0] ? most[0].years : -1;
if (mostYears < pilot.years) {
return [pilot];
}
if (mostYears === pilot.years) {
most.push(pilot);
}
return most;
}, []);
console.log(mostExpPilot);
Upvotes: 3
Reputation: 198426
You can, though it's not very common idiom:
const oldestPilots = pilots => pilots.reduce((oldest, pilot) => {
if (!oldest.length || oldest[0].years < pilot.years) return [pilot];
if (oldest[0].years == pilot.years) return [...oldest, pilot];
return oldest;
}, [])
Upvotes: 3