Skip to content
Advertisement

Define custom parameters inside javascript compare functions in JavaScript?

I have an array of objects that needs sorting by last name, however the object only has firstname and fullname parameters, so for last name I have to use fullname.replace((firstname + " "), ""). Example array below.

const names = [
        {
            firstname: "John",
            fullname: "John Doe"
        },
        {
            firstname: "Amber",
            fullname: "Amber Smith"
        },
        {
            firstname: "Michael",
            fullname: "Michael Smith"
        },
        {
            firstname: "Jessica",
            fullname: "Jessica Kelly Charles"
        }
    ]

While I can use the “replace” every time inside a sort compare function, I’d much rather have something like this:

names.sort(function(a, b) {
            const lastname = fullname.replace((firstname+ " "), "");
            if (a.lastname < b.lastname) {
                return -1;
            } else if (a.lastname > b.lastname) {
                return 1;
            }
            return 0;
        });

Obviously lastname comes up as undefined. This has been rather hard to google for, and I think I’m missing some JavaScript basics here, but would greatly apprecite your help in helping me learn to write better code.

Advertisement

Answer

Your best bet is to modify the source of the array so it stores lastname upon collection.

If you can’t do that:

Unless you do a prep pass through your array adding a lastname property, you’ll have to compute it each and every time your sort callback is called, for both a and b.

names.sort((a, b) => {
    const alast = a.fullname.replace(a.firstname + " "), "");
    const blast = b.fullname.replace(b.firstname + " "), "");
    return alast.localeCompare(blast);
});

(Note I used localeCompare, which is always a better choice for names and other natural language strings than < and >. For instance, ask the French whether รง should really come after z as it does with < and >. ๐Ÿ˜‰ )

That will recompute the lastname for the same object repeatedly, though, since the same object may be passed to sort (as either a or b) repeatedly. If you think that may be a problem, you could do that prep pass I mentioned:

// Build a map of entry to last names
const lastnames = new Map(names.map(entry => {
    const lastname = entry.fullname.replace(entry.firstname + " ", "");
    return [entry, lastname];
}));
// sort
names.sort((a, b) => {
    return lastnames.get(a).localeCompare(lastnames.get(b));
});
User contributions licensed under: CC BY-SA
7 People found this is helpful
Advertisement