Android Code Snippet Student Position Ranking

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.

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
 

Claude Obiri Amadu

Member
Licensed User
Longtime User
Sample Output

image_2022-12-21_145316410.png
 
Top