Reputation: 6697
I have an array:
const array = [
{ name: 'b' },
{ name: 'a' },
{ name: 'c' },
]
The goal here is to keep the same array but to add a new property on each object based on its position if the array was sorted:
const array = [
{ name: 'b', sortIndex: 1 },
{ name: 'a', sortIndex: 0 },
{ name: 'c', sortIndex: 2 },
]
I came up with a plan to just sort the array based on the name. Then loop through it and add the index to get this:
const array = [
{ name: 'a', sortIndex: 0 },
{ name: 'b', sortIndex: 1 },
{ name: 'c', sortIndex: 2 },
]
Then I would loop through the original array and do a findIndex against the sorted array to get the index but that seems like terrible code with so many loops and stuff. Any ideas on how to make this better?
export function setSortIndexes(series) {
const clone = cloneDeep(series);
const sorted = orderBy(clone, [
(x) => (x.name ? x.name.toLowerCase() : null),
]);
sorted.forEach((x, i) => {
x.sortIndex = i;
});
series.forEach(x => {
const index = sorted.findIndex((s) => s.name === x.name);
if (index !== -1) {
x.sortIndex = sorted[index].sortIndex;
}
});
return series;
}
Upvotes: 0
Views: 1254
Reputation: 22320
you can do that:
no need to duplicate objects (or some of its elements) in a new array. an array of pointers to these objects is sufficient
const array =
[ { name: 'b'}
, { name: 'a'}
, { name: 'c'}
]
array // create a new array
.map(o=>({o})) // of pointers ( o ) to refer each array objects
.sort((a,b)=>a.o.name.localeCompare(b.o.name)) // sort
.forEach((_,i,a)=>a[i].o.sortIndex = i ) // add the sortIndex attr
console.log(array)
Upvotes: 1
Reputation: 74761
Create a temporary array to sort, including the original index.
Sort by the name field
Add index to the original object.
array
.map((e, i) => ({ name: e.name, originalIndex: i }))
.sort((a, b) => a.name.localeCompare(b.name))
.forEach((e, i) => array[e.originalIndex].sortIndex = i)
Upvotes: 1