Home > Mobile >  Define custom parameters inside javascript compare functions in JavaScript?
Define custom parameters inside javascript compare functions in JavaScript?

Time:01-19

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.

CodePudding user response:

You are just declaring a new variable trying to access it via object's property. You should map your data in the first place like:

const names = [
    {
        firstname: "John",
        fullname: "John Doe"
    },
    {
        firstname: "Amber",
        fullname: "Amber Smith"
    },
    {
        firstname: "Michael",
        fullname: "Michael Smith"
    },
    {
        firstname: "Jessica",
        fullname: "Jessica Kelly Charles"
    }
].map(person => ({
    ...person, 
    lastName: person.fullName.replace(person.firstName   ' ', '')
}));

After mapping your data like that, you can use .lastName in the place you need.

names.sort(function(a, b) {
    if (a.lastName < b.lastName) {
        return -1;
    } else if (a.lastName > b.lastName) {
        return 1;
    }
    return 0;
});

CodePudding user response:

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));
});
  •  Tags:  
  • Related