This is part of the Semicolon&Sons Code Diary - consisting of lessons learned on the job. You're in the dumb-mistakes-and-gotchas category.
Last Updated: 2024-11-21
This sort function below ran without throwing any exceptions so I hastily assumed it was giving accurate results. (In reality I should have had unit tests - but I was under a lot of pressure to get this code out yesterday)
// Find the best match deal by timestamp
function getMatchingDeal(deals, receivedAt) {
const leastDistanceInTime = (timestampA, timestampB) => {
const timeDistanceA = Math.abs(timestampA - receivedAt)
const timeDistanceB = Math.abs(timestampB - receivedAt)
// case 1: timestampA is 2017; timestamp B is 2019; received at 2017
// => timeDistanceA is 0.001; timeDistanceB = 2
// => we want A to rank before B in sort => must return a negative
// case 2: swap around A and B; thus timeDistanceA is 2 and b is
// 0.01
const difference = timeDistanceA - timeDistanceB
return difference
}
return deals.sort(leastDistanceInTime)[0]
}
But, in fact the results were off. But when I added print logs, I saw that the
variables created within the inner function (leastDistanceInTime
) were all
"NaN".
console.log(timeDistanceA, timeDistanceB, difference)
=> NaN, NaN, NaN
Next I logged the inputs of this inner function leastDistanceInTime
:
console.log(timestampA, timestampB)
=> {dealId: 1145451421, timestamp: 1572961078419} {dealId: 372287585, timestamp: 1538483209706}
AHA - these were complex objects, not mere timestamps, as my function signature and code had assumed. My naming was wrong because I had wrongly assumed these were timestamps instead of objects with a timestamp key.
I fixed by rewriting to accept deal objects instead of timestamps:
const leastDistanceInTime = (dealA, dealB) => {
const timestampA = dealA.timestamp
const timestampB = dealB.timestamp
const timeDistanceA = Math.abs(timestampA - receivedAt)
const timeDistanceB = Math.abs(timestampB - receivedAt)
// case 1: timestampA is 2017; timestamp B is 2019; received at 2017
// => timeDistanceA is 0.001; timeDistanceB = 2
// => we want A to rank before B in sort => must return a negative
// case 2: swap around A and B; thus timeDistanceA is 2 and b is
// 0.01
const difference = timeDistanceA - timeDistanceB
if (Number.isNaN(difference)) {
throw new Error("Cannot sort on NaN")
}
return difference
}
return deals.sort(leastDistanceInTime)[0]