I'm dealing with immutable objects.
I sort data by thisweekNumber
as you can see below.
data.sort(function (a, b) {
return b.thisweekNumber - a.thisweekNumber;
})
For exmaple,
data = [
{name: A, thisweekNumber: 3},
{name: B, thisweekNumber: 5},
{name: C, thisweeknumber: 1},
{name: D, thisweekNumber: 4}
{name: E, thisweekNumber: 4}
]
I sort them B -> D -> E -> A -> C
So I want to put Index to them in this order:
data = [
{name: A, thisweekNumber: 3, index: 3},
{name: B, thisweekNumber: 5, index: 1},
{name: C, thisweeknumber: 1, index: 4},
{name: D, thisweekNumber: 4, index: 2}
{name: E, thisweekNumber: 4, index: 2}
]
BUT here, I want to recognize same thisweekNumber of D and E.
Since they both have 4.
So Index will be like above.
How can I make this array in JavaScript
?
CodePudding user response:
The simplest thing I can think of is to do it after sorting, with a simple loop:
let index = 1;
for (let n = 0; n < data.length; n) {
const current = data[n];
current.index = index;
// See if the next one (if any) matches this one
if (data[n 1]?.thisweekNumber !== current.thisweekNumber) {
index;
}
}
const data = [
{ name: "A", thisweekNumber: 3 },
{ name: "B", thisweekNumber: 5 },
{ name: "C", thisweeknumber: 1 },
{ name: "D", thisweekNumber: 4 },
{ name: "E", thisweekNumber: 4 },
];
data.sort(function (a, b) {
return b.thisweekNumber - a.thisweekNumber;
// return b.thisweekFeedNumber - a.thisweekFeedNumber;
});
let index = 1;
for (let n = 0; n < data.length; n) {
const current = data[n];
current.index = index;
// See if the next one (if any) matches this one
if (data[n 1]?.thisweekNumber !== current.thisweekNumber) {
index;
}
}
console.log(data);
.as-console-wrapper {
max-height: 100% !important;
}
Note the use of optional chaining in the if
.
In a comment you've said:
thanks i understand the concept ! but my object seems not extensible in the process 'current.index = index'. erorr says : cannot add property index, object is not extensible.
You didn't mention that in the question. If you're dealing with immutable objects, you'll need to create new objects (probably in a new array). Creating the objects is typically done using spread syntax:
const newObject = {
...oldObject,
newProperty: "new value"
};
You can easily do that in the loop above, pushing to an in-scope array:
const data = [
{ name: "A", thisweekNumber: 3 },
{ name: "B", thisweekNumber: 5 },
{ name: "C", thisweeknumber: 1 },
{ name: "D", thisweekNumber: 4 },
{ name: "E", thisweekNumber: 4 },
];
data.sort(function (a, b) {
return b.thisweekNumber - a.thisweekNumber;
// return b.thisweekFeedNumber - a.thisweekFeedNumber;
});
let index = 1;
const result = [];
for (let n = 0; n < data.length; n) {
const current = data[n];
result.push({
...current,
index,
});
// See if the next one (if any) matches this one
if (data[n 1]?.thisweekNumber !== current.thisweekNumber) {
index;
}
}
console.log(result);
.as-console-wrapper {
max-height: 100% !important;
}
...or via map
:
const data = [
{ name: "A", thisweekNumber: 3 },
{ name: "B", thisweekNumber: 5 },
{ name: "C", thisweeknumber: 1 },
{ name: "D", thisweekNumber: 4 },
{ name: "E", thisweekNumber: 4 },
];
data.sort(function (a, b) {
return b.thisweekNumber - a.thisweekNumber;
// return b.thisweekFeedNumber - a.thisweekFeedNumber;
});
let index = 1;
const result = data.map((current, n) => {
const element = {
...current,
index,
};
// See if the next one (if any) matches this one
if (data[n 1]?.thisweekNumber !== current.thisweekNumber) {
index;
}
return element;
});
console.log(result);
.as-console-wrapper {
max-height: 100% !important;
}
The map
version is probably more idiomatic.
CodePudding user response:
Put all the unique thisweekNumber
values in an array. Sort that array, then get their indexes.
const data = [
{name: 'A', thisweekNumber: 3},
{name: 'B', thisweekNumber: 5},
{name: 'C', thisweeknumber: 1},
{name: 'D', thisweekNumber: 4},
{name: 'E', thisweekNumber: 4}
];
const weeknumbers = [...new Set(data.map(e => e.thisweekNumber))].sort((a, b) => b - a);
data.forEach(el => el.index = weeknumbers.indexOf(el.thisweekNumber) 1);
console.log(data);
CodePudding user response:
not the prettiest solution but here you go:
data.forEach((item, index) => {
item.index =
data[index - 1]?.index &&
item.thisweekNumber === data[index - 1].thisweekNumber
? index
: index 1;
if (item.index - data[index - 1]?.index > 1) {
item.index -= 1;
}
});
I use a simple forEach to iterate over all the elements in the array and use a ternary to set the value of index. Then I check if the current item.index - previous item.index is > 1 and if it is i subtract 1 from the index (to keep the number sequence in order and not skip numbers)