Home > Blockchain >  How to put index as recognizing same number of sorted array in JavaScript?
How to put index as recognizing same number of sorted array in JavaScript?

Time:07-21

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)

  • Related