how do we Alphabetize by Last Name the data that is coming from an array of objects , a thing to take note in here is that there is no separated propert like FirstName and LastName , the property is holding it as fullname (please check my example data below)
So if we alphabetize the data by last name the result would be in this order based on the data below.
One concern also if what if names are "James van der Wal" and "Mary Tyler Moore" and "Erik the Great" and "Madonna"?
What is the efficient way to handle this scenario ? Help would be much appreciated , thanks. Currently I have a solution below but willing to accept inputs. Thanks.
Alexa Bermodes
Bryan Christian
Alen Geizer
Philipp Hym
Mattew Merrillos
Emil Ortizano
Ivana Turnerre
Steven Weinraucherche
#Object - names
[
{
"id": 2,
"display": "Alen Geizer",
"subDisplay": null,
"attribute1": null,
"attribute2": null
},
{
"id": 9,
"display": "Emil Ortizano",
"subDisplay": null,
"attribute1": null,
"attribute2": null
},
{
"id": 10,
"display": "Philipp Hym",
"subDisplay": null,
"attribute1": null,
"attribute2": null
},
{
"id": 11,
"display": "Bryan Christian",
"subDisplay": null,
"attribute1": null,
"attribute2": null
},
{
"id": 12,
"display": "Ivana Turnerre",
"subDisplay": null,
"attribute1": null,
"attribute2": null
},
{
"id": 13,
"display": "Mattew Merrillos",
"subDisplay": null,
"attribute1": null,
"attribute2": null
},
{
"id": 1,
"display": "Alexa Bermudes",
"subDisplay": null,
"attribute1": null,
"attribute2": null
},
{
"id": 2299,
"display": "Steven Weinraucherche",
"subDisplay": null,
"attribute1": null,
"attribute2": null
}
]
#code
#code
getSampleListOfNames() {
this.isLoading = true;
this._sample.getSampleListNames(id, '')
.pipe(
finalize(() => this.isLoading = false),
).subscribe({
next: (res) => {
if (res.data) {
res.data.sort((a,b) => a.display.split(" ")[1] > b.display.split(" ")[1] ? 1: -1);
this.names = res.data;
}
},
error: err => noop,
complete: () => {
this.isLoading = false;
}
});
}
CodePudding user response:
Without additional external input describing what constitutes the name, a rule of thumb I've used is to define the first name as the space delimited first word, and the last name as the rest...
Taking that idea, and sorting with it...
const parseName = fullname => {
const tokens = fullname.split(' ');
const firstname = tokens[0];
const lastname = tokens.slice(1).join(' ');
return {
firstname,
lastname
};
};
const compareNames = (a, b) => {
const parseA = parseName(a);
const parseB = parseName(b);
return parseA.lastname.localeCompare(parseB.lastname);
};
let sorted = ["Mary Tyler Moore", "Madonna", "Erik The Great"].sort(compareNames);
console.log(sorted)
Another edit... With objects, it's worthwhile to cache this computed parsed name so other bits of the app can use it, for example in subsequent sorts...
const parseName = fullname => {
const tokens = fullname.split(' ');
const firstname = tokens[0];
const lastname = tokens.slice(1).join(' ');
return {
firstname,
lastname
};
};
// this new compare compares on the cached 'parsedName' prop
const compareObjects = (a, b) => {
return a.parsedName.lastname.localeCompare(b.parsedName.lastname);
};
// give each object a new parsedName prop
const augmentedData = getData().map(o => ({ parsedName: parseName(o.display), ...o }));
let sorted = augmentedData.sort(compareObjects);
console.log(sorted);
function getData() {
return [{
"id": 2,
"display": "Alen Geizer",
"subDisplay": null,
"attribute1": null,
"attribute2": null
},
{
"id": 9,
"display": "Emil Ortizano",
"subDisplay": null,
"attribute1": null,
"attribute2": null
}, {
"id": 10,
"display": "Philipp Hym",
"subDisplay": null,
"attribute1": null,
"attribute2": null
}, {
"id": 11,
"display": "Bryan Christian",
"subDisplay": null,
"attribute1": null,
"attribute2": null
}, {
"id": 12,
"display": "Ivana Turnerre",
"subDisplay": null,
"attribute1": null,
"attribute2": null
}, {
"id": 13,
"display": "Mattew Merrillos",
"subDisplay": null,
"attribute1": null,
"attribute2": null
},
{
"id": 1,
"display": "Alexa Bermudes",
"subDisplay": null,
"attribute1": null,
"attribute2": null
}, {
"id": 2299,
"display": "Steven Weinraucherche",
"subDisplay": null,
"attribute1": null,
"attribute2": null
}
]
}
Caching the parse is a good idea for another reason: since the choice of firstname / lastname is a little arbitrary, the parsed property makes that decision explicit and centralized. With it, your colleagues using the objects (or future you) might think twice before applying their own cultural intuition to the names, causing an inconsistency.
CodePudding user response:
Assuming a = [as in question] and last name means the string following the final " ", you could do it like this:
const last = o => o.display.split(" ").pop();
a.sort((a, b) => last(a).localeCompare(last(b)))
