I am trying to dynamically sort a simple object by the property name.
sampleArr: {
name: string;
age: number;
}[ ] = [
{ name: "Michael", age: 21},
{ name: "Adam", age: 35 },
{ name: "Zoe", age: 11 },
];
I understand that sorting by the string column is different to sorting by the number column so let's put that aside for the moment. Let's focus on the string column.
this.sampleArr.sort((a, b) => a.name.localeCompare(b.name))
The code above work perfectly fine. However, I have hard coded the name column. I would like to make that dynamic.
Let's say I had an array with multiple string fields where I give the user the choice to chose the column to sort by. For example...I want to be able to pass in the column name as a string (sortBy) and use that to determine the field to sort by.
So essentially, I would be replacing the hard coded a.name and b.name with a[sortBy] and b[sortBy]
sampleArrSort(sortBy: string) {
// this.sampleArr.sort((a, b) => a.name.localeCompare(b.name))
this.sampleArr.sort((a, b) => a[sortBy].localeCompare(b[SortBy]))
console.log(this.sampleArr);
}
However, I get the following error.
Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ name: string; age: number; }'.
No index signature with a parameter of type 'string' was found on type '{ name: string; age: number; }'.ts(7053)
Does anyone know how to solve this?
Thanks for your help.
I have searched everywhere and can't seem to adapt code snippets that I have found to my scenario. I may need to use keyOf? I am not sure
If you want to dynamically pass the property names it is important that all of the values can be passed to the sampleArrSort
function.
You can create an interface of your array item and use said interface to pass a keyof Person
to the sampleArrSort
function.
Since you have both string
and also number
values, you will need to check the types of the values inside the sampleArrSort
function and compare the values accordingly.
interface Person {
name: string;
age: number;
}
const sampleArr: Person[] = [
{ name: "Michael", age: 21},
{ name: "Adam", age: 35 },
{ name: "Zoe", age: 11 },
];
function sampleArrSort(sortBy: keyof Person): void {
sampleArr.sort((a, b) => {
const valueA = a[sortBy];
const valueB = b[sortBy];
if (typeof valueA === 'string' && typeof valueB === 'string') {
return valueA.localeCompare(valueB);
} else if (typeof valueA === 'number' && typeof valueB === 'number') {
return valueA - valueB;
} else {
throw new Error(`Unsupported type for sorting: ${typeof valueA}`);
}
});