Best way to find out user rank position based on a single variable and multiple variables.[PHP-Laravel]

This is surely a very challenging task when it comes to finding out the user rank position of the ‘scores’ table. Mostly when it comes to the multivariable calculation. Like, get a position in terms of score, time, number of attempts, etc.

In this story, I will cover both finding method step by step and also the best approach we should use for this calculation.

[Note: In here I will be using Eloquent ORM model for query data. If you know laravel it’s quite familiar with you.]

To find out the user position based on a single variable (here, which is score) is pretty much easy.

Single Variable:

Scores table

From the table above, we see there is only one variable that is ‘score’. Using this, we need to find out the rank of the user.

To find the rank position we need to first sort the table based on score variable in descending order.

$scores = Score::orderBy(‘score’, ‘desc’)->get();

Which will become

If we want to view visual representation it will become


//JSON VIEW
[
{
“user_id”: 4,
“score”: 70,
},
{
“user_id”: 2,
“score”: 40,
},
{
“user_id”: 1,
“score”: 30,
},
{
“user_id”: 5,
“score”: 20,
},
{
“user_id”: 3,
“score”: 10,
},
]

Look closely, in this JSON view, each array object is in descending order. It means that the highest scored user id becomes 1st in position and the lowest one becomes the last. We know each of the array element or object has an index value.

Like:

[
0 : {
“user_id”: 4,
“score”: 70,
},
1: {
“user_id”: 2,
“score”: 40,
},
2: {
“user_id”: 1,
“score”: 30,
},
3: {
“user_id”: 5,
“score”: 20,
},
4: {
“user_id”: 3,
“score”: 10,
},
]

So from this, we can easily identify the user position of user id 1. and its index value is 2. It means that user id 1 has position 3 because the index value starts from 0.

But how to get this index value by your code?

For this, we should use the array_search method.

Multiple Variable:

Like a single variable, we can also get user position from the score table in multiple variables.

Score table

Notice there, an extra column is added beside the score table, which is ‘time’.

It’s necessary. The more variable you use, the more accurate your calculation will be. Example: If you notice user id 1 and 3 both got the same marks, but whom should we prioritize first based on what? If we look time column for user id 1 and 3 we would notice there user 1 time is less than user 3. So user id 1 goes before 3. that’s how we should evaluate.

So we need to sort the table based on the score first at descending order and then we have to sort it again based on time in ascending order.

$scores = Score::orderBy(‘score’, ‘desc’)->orderBy('time', 'asc')->get();

It will be sorted as

Sorted view

Then use the code which we previously used.

Problem:

The code I used in these two examples has some drawbacks.

Like array_search is a built-in function in PHP which does a linear search.

Whereas linear search is a very bad experience when it comes to a huge amount of data.

You might face server slow issues or execution time error when it will be a large data table.

So how can we solved this issue?

Best Solution

I don’t know this solution is very best or not. But trust me, It’s so fast in execution.

This time I will use the same sorting function which I did previously but this time something different.

$Scores= Score::orderBy(‘score’, ‘desc’)->orderBy(‘time’, ‘asc’)->pluck(‘user_id’)->toArray();

Notice I used pluck method to get user_id in a set of array.

//JSON VIEW
[
4,
2,
1,
3,
5,
]

Notice above, the JSON view, all user id is a set of an array and sorted based on score and time.

Now we will use array_flip to map the value and index. Basically, it will be assigned array value to index and index to value.

Example:

//JSON VIEW
{
“4”: 0,
“2”: 1,
“1”: 2,
“3”: 3,
“5”: 4,
}

Now if we want to find the user id 1 position!

Just write $scores[“1”] and it will return 2

If you want to know 3 ? just write $scores[“3”] and it will return 3

No more linear search, no more for each check,

Just call the index value and get the position, as simple as that.

This algorithm we can use single or multiple variables in both cases.

What algorithm you are using for this calculation? Please share your experience in the comments below.

Love to work with new technologies, explore new challenges and watch Movies & Anime