Tengo 3 casos de prueba diferentes, cada uno de los cuales se pasa a la función getEarliest a continuación:
{} { '2022-04-29': 1 } { '2022-04-29': 3, '2022-04-30': 2, '2022-04-28': 3, '2022-05-02': 2 } De cada caso de prueba, quiero devolver la clave: valor con la fecha más pequeña y el valor más grande. Mi problema está en el tercer caso de prueba, '2022-04-29': 3 en lugar de '2022-04-28': 3
getEarliest = dates => { return Object.keys(dates).reduce((prev, curr) => { if (dates[curr] > prev.date) { return { val: dates[curr], date: curr }; } else { return prev; } }, { val: 0, date: null }); } caso de prueba de resultado esperado 1: { val: 0, date: null }
caso de prueba de resultado esperado 2: { val: 1, date: '2022-04-29' }
caso de prueba de resultado esperado 3: { val: 3, date: '2022-04-28' }
Parece que solo necesita sort el objeto por dos parámetros:
const test1 = {}; const test2 = { '2022-04-29': 1 }; const test3 = { '2022-04-29': 3, '2022-04-30': 2, '2022-04-28': 3, '2022-05-02': 2 }; const test4 = { '2022-04-29': 4, '2022-04-28': 4, '2022-04-30': 4, '2022-05-02': 2 }; const getEarliest = (dates) => { const [date, val] = Object.entries(dates) .sort(([k1, v1], [k2, v2]) => v2 - v1 || Date.parse(k1) - Date.parse(k2) ) .at(0) ?? [null, 0]; return { val, date }; }; console.log(getEarliest(test1)); console.log(getEarliest(test2)); console.log(getEarliest(test3)); console.log(getEarliest(test4)); .as-console-wrapper {max-height: 100% !important; top: 0} Y el mismo resultado con reduce :
const test1 = {}; const test2 = { '2022-04-29': 1 }; const test3 = { '2022-04-29': 3, '2022-04-30': 2, '2022-04-28': 3, '2022-05-02': 2 }; const test4 = { '2022-04-29': 4, '2022-04-28': 4, '2022-04-30': 4, '2022-05-02': 2 }; const getEarliest = (dates) => { const [date, val] = Object.entries(dates) .reduce((prev, curr) => (curr[1] - prev[1] || Date.parse(prev[0]) - Date.parse(curr[0])) > 0 ? curr : prev , [null, 0]); return { val, date }; }; console.log(getEarliest(test1)); console.log(getEarliest(test2)); console.log(getEarliest(test3)); console.log(getEarliest(test4)); .as-console-wrapper {max-height: 100%!important;top:0 }En su código prev.date valor de fecha anterior es inicialmente nulo. entonces reduce() siempre devolverá el objeto inicial.
Prueba este código, te ayudará.
getEarliest = (dates) => { if (Object.keys(dates).length > 0) { let date = Object.keys(dates).reduce((prev, curr) => { if (prev > curr) { return curr; } else { return prev; } }); return { val: dates[date], date: date } } else { return { val: 0, date: null } } }Porque tiene 2 condiciones de clasificación, por lo que deben colocarse en un orden determinado. De sus ejemplos, asumo que el orden es: "valor más grande" -> "fecha más pequeña". Entonces su if será como a continuación:
getEarliest = (dates) => { return Object.keys(dates).reduce( (prev, curr) => { if (dates[curr] > prev.val || (dates[curr] === prev.val && curr < prev.date)) { return { val: dates[curr], date: curr, } } else { return prev } }, { val: 0, date: null, } ) }