Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

103
Visualizações
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 Respostas
Responde à pergunta

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 Relatório

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 Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda