2
\$\begingroup\$

So I have notes that have a lastEdit which is a timestamp in milliseconds and a unique id. I want to find the id of the note that has the greatest lastEdit value.

I tried the good old fashion way, and then figured there must be an es6 way of doing this, but even after a lot of struggling and getting it to work, it's even messier.

I'm wondering if there's a cleaner / better way of doing this. I don't care about ties in timestamp or performance much. Here's what I got so far:

const getMostRecentNote = () => {
    let maxTimestamp = 0;
    let maxId = -1;
    notes.forEach((n) => {
        if (maxTimestamp < n.lastEdit) {
            maxTimestamp = n.lastEdit;
            maxId = n.id;
        }
    });

    // https://stackoverflow.com/a/43576363/4907950
    const rtn = notes.reduce((acc, note) => {
        if (acc.maxTimestamp === undefined) {
            acc = { maxTimestamp: -1, maxId: -1 };
        }
        if (note.lastEdit > acc.maxTimestamp) {
            acc = { maxTimestamp: note.lastEdit, maxId: note.id };
        }
        return acc;
    }, {}).maxId;

    return [maxId, rtn];
};

Update: realized I can just logical or the reduce one:

const rtn = notes.reduce((acc, note) => {
        if (
            acc.maxTimestamp === undefined ||
            note.lastEdit > acc.maxTimestamp
        ) {
            acc = { maxTimestamp: note.lastEdit, maxId: note.id };
        }
        return acc;
    }, {}).maxId;

I still like the simple version better but let me know what you think or if you can think of something simpler : )

Update 2: Even simpler:

    const rtn = notes.reduce(
        (acc, note) =>
            acc.maxTimestamp === undefined || note.lastEdit > acc.maxTimestamp
                ? { maxTimestamp: note.lastEdit, maxId: note.id }
                : acc,
        {}
    ).maxId;

or:

    const rtn = notes.reduce(
        (acc, note) =>
            note.lastEdit > acc.maxTimestamp
                ? { maxTimestamp: note.lastEdit, maxId: note.id }
                : acc,
        { maxTimestamp: -1 }
    ).maxId;
\$\endgroup\$
4
  • \$\begingroup\$ Maybe a custom sort function on the array to sort by timestamp? would be aO(nlogn) for a O(n) problem though \$\endgroup\$ Commented Feb 2, 2022 at 6:19
  • \$\begingroup\$ Would return notes.sort((a, b) => b.lastEdit - a.lastEdit)[0].id; be considered bad code? \$\endgroup\$ Commented Feb 2, 2022 at 6:24
  • \$\begingroup\$ I should add for my use case the sort way runs seemingly instantly with 250 items, which is the max I allow my users (could change) \$\endgroup\$ Commented Feb 2, 2022 at 6:26
  • \$\begingroup\$ Also sort mutates the original object, but that's fine in this case. Worth noting for others viewing this in the future. \$\endgroup\$ Commented Feb 2, 2022 at 6:36

2 Answers 2

2
\$\begingroup\$

A short review;

First a meta remark; providing 4 versions isn't really in the spirit of CodeReview ;)

  • Since it seems to return the id instead of the note, you probabably want to call the function getMostRecentNoteId or really return the note
  • sort would help, but changes notes, since we only care about id and lastEdit we could create a new list with just those values
  • Not a big fan of rtn, I am a big fan of spelled out words or Spartan variables, how about out?
  • I am a big fan of the function keyword, it's more readable to me
  • notes seems to be a global, that is definitely not best practice

Mandatory counter-proposal;

function getMostRecentNoteInfo(notes){

  const bareNotes = notes.map(o=>[o.maxId, o.maxTimestamp]);
  return bareNotes.sort((a, b) => a.lastEdit - b.lastEdit).pop();

}
\$\endgroup\$
1
  • \$\begingroup\$ Thank you for the in depth reply. I agree with most of your feedback and appreciate the function you provided. \$\endgroup\$ Commented Aug 1, 2023 at 2:21
1
\$\begingroup\$

Your solutions are complicated.


A simpler solution.

// mostRecentNote returns the id of the note 
// with the most recent lastEdit timestamp.
function mostRecentNote(notes) {
    return notes.reduce((prev, curr) => { 
            return (prev.lastEdit > curr.lastEdit) ? prev : curr;
        }, 
        [],
    ).id;
}
\$\endgroup\$
1
  • \$\begingroup\$ Nice, this is quite clean and readable imo! \$\endgroup\$ Commented Aug 1, 2023 at 2:22

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.