klevisx
klevisx

Reputation: 182

Print two or more occurrences using reduce() in Javascript

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

Answers (4)

Dexygen
Dexygen

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

RK_15
RK_15

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

T.J. Crowder
T.J. Crowder

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

Amadan
Amadan

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

Related Questions