En este momento tengo un ciclo for repasando las fechas. Primero clasifico el orden y luego tomo la primera fecha de cada año, pero siento que esto podría usarse con .reduce() en su lugar y convertir los resultados con Object.values(result) me devolvería la matriz o 3 fechas.
Reducir con un tenerario me daría la fecha general más baja. Pero estoy atascado donde necesito devolver la fecha más baja de cada año dentro de la sección.
.reduce((a,b) => a = moment(a) < moment(a) ? a : b return a )Si hay mejores formas de lograr el resultado final, soy todo oídos.
@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]); } } } }Problema: https://stackblitz.com/edit/angular-moment-example-z7m92c?file=app%2Fapp.component.ts
Editar. Terminé usando algo como esto.
.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());No pretendo saber todo lo que está pasando, pero una manera fácil de encontrar la primera cita es con .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' } */La idea de usar .reduce() es una forma posible de lograr el objetivo. Combínelo con Object.values() y debajo hay una posible implementación:
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>Explicación
.reduce() para obtener un object con accesorios como el year y valores como la fecha más temprana de ese añoObject.values() para extraer solo los valores (que serán la fecha más temprana en cada año dado)Cómo funciona reducir
fin es el agregador y se establece inicialmente en {} (objeto vacío)itm es el iterador (es decir, cada fecha en la matriz origData )year del itm actual ya existe, compruebe si el valor existente en el agregador fin[moment(itm).format('YYYY')] es menor que itm (es decir, si la fecha es anterior a la de itm )itm