Hello everyone and Happy Holidays
So I was searching the community for a snippet for student ranking for a system I was building last month but never came accross a what I needed. I found a JavaScript on stackoverflow and re-wrote it in b4x
So I'm sharing for future/existing members who may need it.
The B4X Code Below
The Type can be changed to anything as long as there is something to enable ranking (ie. TotalScore, Rank)
Filters the List to find similar scores and returns a list(rList).
Filter - is the item to be filtered out in the List
This performs the overall calculations returning a List with the Ranks assigned
Similar to CalculatePosition but only gets one Students position
Attached the number suffix(ie 1st, 2nd, 3rd)
Data to be based can be JSON, an Array or List with objects
So I was searching the community for a snippet for student ranking for a system I was building last month but never came accross a what I needed. I found a JavaScript on stackoverflow and re-wrote it in b4x
So I'm sharing for future/existing members who may need it.
Original from StackOverflow:
function calculatePosition(data){
var json = data;
json.sort((a, b) => b.total - a.total);
for (let i = 0; i < json.length; i++) {
let totalPoints = json[i].total;
let studentsWithRank = json.filter(student => student.total === totalPoints);
for (let student of studentsWithRank) {
student.rank = i + 1;
}
i += studentsWithRank.length - 1;
}
console.log(json);
return json;
}
The B4X Code Below
The Type can be changed to anything as long as there is something to enable ranking (ie. TotalScore, Rank)
Data Type:
Type StudentScore(Total As Int, Year As String, StudentID As String, Term As Int, Class As String, Rank As Int)
Filters the List to find similar scores and returns a list(rList).
Filter - is the item to be filtered out in the List
Filter Array or List:
Public Sub FilterList(List As List, Filter As Object) As List
Dim rList As List : rList.Initialize
For i = 0 To List.Size-1
Dim score As StudentScore = List.Get(i)
If score.Total == Filter Then
rList.Add(score)
End If
Next
Return rList
End Sub
This performs the overall calculations returning a List with the Ranks assigned
Calculate Position:
Public Sub CalculatePosition(List As List) As List
Dim posList As List : posList.Initialize
For i = 0 To List.Size-1
Dim score As StudentScore = List.Get(i)
Dim totalPoints As Int = score.Total
Dim studentsWithRank As List = FilterList(List,totalPoints)
For Each student As StudentScore In studentsWithRank
student.Rank = i + 1
Log(student.Rank)
posList.Add(student)
Next
i = i + studentsWithRank.Size-1
Next
Return posList
End Sub
Similar to CalculatePosition but only gets one Students position
Get Position:
Public Sub GetPosition(List As List, StudentID As String) As Int
Dim Position As Int
Dim posList As List : posList.Initialize
For i = 0 To List.Size-1
Dim score As StudentScore = List.Get(i)
Dim totalPoints As Int = score.Total
Dim studentsWithRank As List = FilterList(List,totalPoints)
For Each student As StudentScore In studentsWithRank
student.Rank = i + 1
posList.Add(student)
Next
i = i + studentsWithRank.Size-1
Next
For i = 0 To posList.Size-1
Dim score As StudentScore = posList.Get(i)
If score.StudentID == StudentID Then
Position = score.Rank
End If
Next
Return Position
End Sub
Attached the number suffix(ie 1st, 2nd, 3rd)
Ordinal Suffix Of:
public Sub OrdinalSuffixOf(i As Int) As String
If i == 0 Then
Return i
Else
Dim j As Int = i Mod 10
Dim k As Int = i Mod 100
If (j == 1 And k <> 11) Then
Return i & "st"
End If
If (j == 1 And k <> 11) Then
Return i & "st"
End If
If (j == 2 And k <> 12) Then
Return i & "nd"
End If
If (j == 3 And k <> 13) Then
Return i & "rd"
End If
Return i & "th"
End If
End Sub
Data to be based can be JSON, an Array or List with objects
Usage Sample:
Dim List As List : List.initialize
Dim DataString As String = $"[{"total":603,"yeargroup":"2022\/2023","student_id":70,"term":3,"class":"KG 1"},{"total":603,"yeargroup":"2022\/2023","student_id":74,"term":3,"class":"KG 1"},{"total":603,"yeargroup":"2022\/2023","student_id":124,"term":3,"class":"KG 1"},{"total":168,"yeargroup":"2022\/2023","student_id":82,"term":3,"class":"KG 1"},{"total":166,"yeargroup":"2022\/2023","student_id":72,"term":3,"class":"KG 1"},{"total":163,"yeargroup":"2022\/2023","student_id":81,"term":3,"class":"KG 1"},{"total":153,"yeargroup":"2022\/2023","student_id":472,"term":3,"class":"KG 1"},{"total":153,"yeargroup":"2022\/2023","student_id":84,"term":3,"class":"KG 1"},{"total":150,"yeargroup":"2022\/2023","student_id":77,"term":3,"class":"KG 1"},{"total":148,"yeargroup":"2022\/2023","student_id":79,"term":3,"class":"KG 1"},{"total":142,"yeargroup":"2022\/2023","student_id":76,"term":3,"class":"KG 1"},{"total":138,"yeargroup":"2022\/2023","student_id":73,"term":3,"class":"KG 1"},{"total":136,"yeargroup":"2022\/2023","student_id":471,"term":3,"class":"KG 1"},{"total":135,"yeargroup":"2022\/2023","student_id":75,"term":3,"class":"KG 1"},{"total":131,"yeargroup":"2022\/2023","student_id":83,"term":3,"class":"KG 1"},{"total":125,"yeargroup":"2022\/2023","student_id":80,"term":3,"class":"KG 1"},{"total":121,"yeargroup":"2022\/2023","student_id":473,"term":3,"class":"KG 1"},{"total":102,"yeargroup":"2022\/2023","student_id":71,"term":3,"class":"KG 1"},{"total":98,"yeargroup":"2022\/2023","student_id":470,"term":3,"class":"KG 1"}]"$
Dim DataList As List
Dim Parser As JSONParser
Parser.Initialize(DataString)
DataList = Parser.NextArray
For s = 0 To DataList.Size-1
Dim m As Map = DataList.Get(s)
Dim score As StudentScore
score.Initialize
score.Total = m.Get("total")
score.Year = m.Get("yeargroup")
score.StudentID = m.Get("student_id")
score.Term = m.Get("term")
score.class = m.Get("class")
List.Add(score)
Log(OrdinalSuffixOf(GetPosition(List,score.StudentID)))
Next