How to sort array without changing order of same values

I have array of objects and I want to sort them by points from bigger to smaller. But if two or more persons have same number of points, they should have same position number and sorted by name (name is unique).

For example if you have function:

[
  {
    name: "John",
    points: 100,
  },
  {
    name: "Bob",
    points: 130,
  },
  {
    name: "Mary",
    points: 120,
  },
  {
    name: "Kate",
    points: 120,
  },
]

Output should be:

[
  {
    name: "Bob",
    points: 130,
    position: 1,
  },
  {
    name: "Kate",
    points: 120,
    position: 2,
  },
  {
    name: "Mary",
    points: 120,
    position: 2,
  },
  {
    name: "John",
    points: 100,
    position: 4,
  },
]

But when I try solve this problem, the output was:
image

My code is:

function ranking(people) {
  return people.sort((a, b) => a.points < b.points);
}

What I need to include on my code to solve the problem?

1 Like

The position is quite easily achieved by also keeping track of the number of times you’ve seen the same number. That way when you work your way through the sorted list, you can just do index - timesSeen and you’ll achieve your 1 2 2 4 type of positioning.

Hello everyone,
I’m solving coding challenge Ranking position on codewars.
I wrote the code but it seems that I did not pass the challenge.

My code so far:

function ranking(people) {
  return people
    .sort((a, b) => a.name.localeCompare(b.name))
    .sort((a, b) => b.points - a.points)
    .map((item, i) => {
      item.position = i + 1;
      let curr = item.points;

      if (people[i + 1] !== undefined) {
        let next = people[i + 1].points;

        if (curr === next) {
          people[i + 1].position = item.position;
        }
      }

      return item;
    });
}

let arr = [
  {
    name: "John",
    points: 100
  },
  {
    name: "Bob",
    points: 130
  },
  {
    name: "Mary",
    points: 120
  },
  {
    name: "Kate",
    points: 120
  }
];

console.log(ranking(arr));

the output should be:

[
  {
    name: "Bob",
    points: 130,
    position: 1,
  },
  {
    name: "Kate",
    points: 120,
    position: 2,
  },
  {
    name: "Mary",
    points: 120,
    position: 2,
  },
  {
    name: "John",
    points: 100,
    position: 4,
  },
]

but my output is little different:

[
  {
    name: "Bob",
    points: 130,
    position: 1,
  },
  {
    name: "Kate",
    points: 120,
    position: 2,
  },
  {
    name: "Mary",
    points: 120,
    position: 3,
  },
  {
    name: "John",
    points: 100,
    position: 4,
  },
]

The different is that the object with Kate name should equal with the object Mary name. But my code doesn’t do that!!!

LINK TO THE CHALLENGE:

It looks like your position value still needs to remove the number of times that the score has been seen.

And then your sorting function needs to take into account both points and name, but yeah.

Personally I found it easier to collapse a list of points and use indexOf, but tracking the number of times seen also works.

So what can I do to fix my code?

Could you help me by writing some code?

The idea of a coding challenge is that you write the code, not us. Copy and pasting doesn’t mean you’ve learned.

So help me, give hints/tips or anything!!!

Paul’s already given you the hint.

Currently, your code is assigning position to be the index +1. But the position isnt always that. Paul’s hint is that you can keep track of the number of times you’ve seen each number of points, and then subtract it from the position (so, if i’ve never seen the number before, position 2 - 0 = 2…then the next number comes along and it’s the same, so i’ve seen it once… 3 -1 = 2… if the next is also the same then 4 - 2 = 2…

I’ll throw an extra hint out there: You only need to keep track of two things: the previous value and the number of times it’s been seen.

2 Likes

Thank you for your hint @m_hutley

Could you give me strategies/steps that can help me understand and solve any coding problem either If I got hints or not?

That’s… a very broad ask.

The basics comes down to understanding three things:
“What is coming in” (easy)
“What is going out” (easy)
“How would I go from in to out, if I were doing it myself?” (not usually that easy)

If you can answer the third one in “english” (read: language of your choice; human language), that’s your program. It’s just a question of translating what you say you would do, into something the computer can do.

Also, keep in mind there isnt AN answer to virtually any and every coding problem you’ll face - there are almost always infinitely many solutions.

3*4 = 12,
but 3+3+3+3 is also 12. Same inputs (3 and 4), same outputs (12), but different methods.

Do you mean the previous value the current value?

Well basically what i mean is you need to be able to detect when the value changes.

You’re looping through the values. Lets say we’ve got… [120 120 120 110].

You start off, you look at the first number, you say “120 is different than [nothing, because this is the first number], so it’s the 0th time i’ve seen this number. The index was 0, so 0-0 (+1 because we’re going from a 0-indexed array to 1-indexed human-speak) is 1.”

The next number comes up. It’s a 120. You need to be able to say “120 is the same as 120, so i’ve seen this number before. It’s the 1th time i’ve seen this number (again, zero-indexing!) so 1-1+1 is 1.”

The next number comes up. It’s a 120. You need to be able to say “120 is the same as 120, so i’ve seen this number before. It’s the 2th time i’ve seen this number (again, zero-indexing!) so 2-2+1 is 1.”

The next number comes up. It’s a 110. You need to be able to say “110 is NOT the same as 120, so i haven’t seen this number before. It’s the 0th time i’ve seen this number, so 3-0+1 is 4.”

So number 3 is the index of the item. The number 0 is the the number of times that you have seen this item before. But what 4 does mean?

The person is in position 4.

[120 120 120 110], in terms of the system’s positioning, is [1 1 1 4]

Okay but how this helps me to sort numbers by name

Read the instruction of the challenge:

In some ranking people collects points. The challenge is sort by points and calulate position for every person. But remember if two or more persons have same number of points, they should have same position number and sorted by name (name is unique).

So I need to sort by name with all items? or the only items that are the same points??

The name thing is a tiebreaker. If multiple people would be in the same position, sort those people by name as well.

So this is another issue.

Now I need also to catch all the same values then sort them by name!!!

Could explain more @Paul_Wilkins?

I didn’t understand very well