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)); });