Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

112
Vistas
How to reduce to find lowest date for each year from section of dates

Right now I have a for-loop going over the dates. I first sort the order and then pluck the first date of each year, but I feel like this could be used with .reduce() instead and converting the results with Object.values(result) would return me the array or 3 dates.

Reducing with one tenerary would get me the lowest overall date. But I am stuck where I need to return the lowest date from each year within the section.

.reduce((a,b) =>
a = moment(a) < moment(a) ? a : b
return a
)

If there are better ways to achive the end result I am all ears.

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
})
export class AppComponent {
  firstDatesOfYear = [];

  data = [
    '2022-02-14T00:00:00',
    '2021-06-14T00:00:00',
    '2021-06-21T00:00:00',
    '2021-11-01T00:00:00',
    '2022-01-10T00:00:00',
    '2022-01-03T00:00:00',
    '2020-07-20T00:00:00',
    '2020-08-31T00:00:00',
    '2020-09-07T00:00:00',
    '2021-02-22T00:00:00',
    '2021-06-07T00:00:00',
    '2022-01-17T00:00:00',
    '2022-01-24T00:00:00',
    '2022-01-31T00:00:00',
  ];

  // find first date of each year from non sorted list of ISO dates
  // result should be ["2020-07-20T00:00:00", "2021-02-22T00:00:00", "2022-01-03T00:00:00"]

  constructor() {
    let temp = this.data
      .map((day) => moment(day))
      .sort((a, b) => a.unix() - b.unix());
    // stuck here, instead of doing the whole following below - should use .reduce()?

    console.log(temp);

    for (let i = 0; i < temp.length; i++) {
      if (i == 0) {
        this.firstDatesOfYear.push(temp[i]);
      } else if (moment(temp[i]).year() != moment(temp[i + 1]).year()) {
        this.firstDatesOfYear.push(temp[i + 1]);
      }
    }
  }
}

Problem: https://stackblitz.com/edit/angular-moment-example-z7m92c?file=app%2Fapp.component.ts

Edit. I ended up using something like this.

.reduce((datesMap, curr) => {
  const date = new Date(curr),
        year = date.getFullYear();

  if (datesMap.has(year)) {
    if (date.getTime() < datesMap.get(year).getTime())
      datesMap.set(year, date);
  } else {
    datesMap.set(year, date);
  }
  
  return datesMap;
}, new Map());
about 4 years ago · Juan Pablo Isaza
2 Respuestas
Responde la pregunta

0

I don't pretend to know everything that's going on, but an easy way to find the first date is with .sort().

const data = [
  "2022-02-14T00:00:00",
  "2021-06-14T00:00:00",
  "2021-06-21T00:00:00",
  "2021-11-01T00:00:00",
  "2022-01-10T00:00:00",
  "2022-01-03T00:00:00",
  "2020-07-20T00:00:00",
  "2020-08-31T00:00:00",
  "2020-09-07T00:00:00",
  "2021-02-22T00:00:00",
  "2021-06-07T00:00:00",
  "2022-01-17T00:00:00",
  "2022-01-24T00:00:00",
  "2022-01-31T00:00:00",
];

const firstDatePerYear = data
  .sort((a, b) => new Date(a) - new Date(b))
  .reduce((acc, curr) => {
    const year = new Date(curr).getFullYear();
    if (!acc[year]) acc[year] = curr;
    return acc;
  }, {});

console.log(firstDatePerYear);

/*
{
  '2020': '2020-07-20T00:00:00',
  '2021': '2021-02-22T00:00:00',
  '2022': '2022-01-03T00:00:00'
}
*/
about 4 years ago · Juan Pablo Isaza Denunciar

0

The idea to use .reduce() is one possible way to achieve the objective. Combine it with Object.values() and below is one possible implementation:

const origData = [
    '2022-02-14T00:00:00',
    '2021-06-14T00:00:00',
    '2021-06-21T00:00:00',
    '2021-11-01T00:00:00',
    '2022-01-10T00:00:00',
    '2022-01-03T00:00:00',
    '2020-07-20T00:00:00',
    '2020-08-31T00:00:00',
    '2020-09-07T00:00:00',
    '2021-02-22T00:00:00',
    '2021-06-07T00:00:00',
    '2022-01-17T00:00:00',
    '2022-01-24T00:00:00',
    '2022-01-31T00:00:00',
  ];
  
  const getFirstDates = (arr = origData) => (
    Object.values(
      arr.reduce(
        (fin, itm) => ({
          ...fin,
          [moment(itm).format('YYYY')]: (
            fin[moment(itm).format('YYYY')] &&
            fin[moment(itm).format('YYYY')] < itm
              ? fin[moment(itm).format('YYYY')]
              : itm
          )
        }),
        {}
      )
    )
  );
  
  console.log(getFirstDates());
<script src="https://unpkg.com/moment@2.29.1/moment.js"></script>

Explanation

  • Use .reduce() to obtain an object with props as the year and values as the earliest date of that year
  • Use Object.values() to extract just the values (which will be earliest date on each given year)

How reduce works

  • fin is the aggregator & is initially set to {} (empty object)
  • itm is the iterator (ie, each date in the origData array)
  • If the year of the current itm already exists, then check if the existing value in the aggregator fin[moment(itm).format('YYYY')] is lesser than itm (ie, whether the date is earlier than the one in itm)
  • If the existing date is earlier, do nothing (ie, return it as-is)
  • Otherwise, repopulate the value with itm
about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda