Task

Find the top   N   salaries in each department,   where   N   is provided as a parameter.

Use this data as a formatted internal data structure (adapt it to your language-native idioms, rather than parse at runtime), or identify your external data source:

Employee Name,Employee ID,Salary,Department
Tyler Bennett,E10297,32000,D101
John Rappl,E21437,47000,D050
George Woltman,E00127,53500,D101
Adam Smith,E63535,18000,D202
Claire Buckman,E39876,27800,D202
David McClellan,E04242,41500,D101
Rich Holcomb,E01234,49500,D202
Nathan Adams,E41298,21900,D050
Richard Potter,E43128,15900,D101
David Motsinger,E27002,19250,D202
Tim Sampair,E03033,27000,D101
Kim Arlich,E10001,57000,D190
Timothy Grove,E16398,29900,D190



Structure Employees
  Name$
  ID$
  Salary.i
  Department$
EndStructure
 
Procedure displayTopEarners(List MyEmployees.Employees(), n)
  Protected filename$ = OpenFileRequester("Top rank per group", "DataFile.txt", "", 0)
  If ReadFile(0, filename$) 
    Protected InData.Employees, txt.s, MaxNameLength
 
    While Eof(0) = 0    
      AddElement(MyEmployees())      
      txt = ReadString(0)
      With MyEmployees()
        \Name$ = StringField(txt, 1, ",")
        \ID$ = StringField(txt, 2, ",")
        \Salary = Val(StringField(txt, 3, ","))
        \Department$ = StringField(txt, 4, ",")
        If Len(\Name$) > MaxNameLength: MaxNameLength = Len(\Name$): EndIf
      EndWith
    Wend
    CloseFile(0) 
  Else
    MessageRequester("Information", "Couldn't open the file!")
    End
  EndIf
 
  If OpenConsole()
    Protected OldDepartment$, count
 
    SortStructuredList(MyEmployees(), #PB_Sort_Descending, OffsetOf(Employees\Salary), #PB_Sort_integer)
    SortStructuredList(MyEmployees(), #PB_Sort_Ascending, OffsetOf(Employees\Department$), #PB_Sort_String)
    ForEach MyEmployees()
      With MyEmployees()
        If \Department$ <> OldDepartment$
          If OldDepartment$ <> ""
            PrintN(#CRLF$)
          EndIf
          OldDepartment$ = \Department$
          PrintN("Department " + \Department$ + #CRLF$ + "---------------")
          PrintN(LSet("Name", MaxNameLength + 3) + LSet("ID", 7) + LSet("Salary", 7))
          count = 0
        EndIf 
        count + 1
        If count <= n
          PrintN(LSet(\Name$, MaxNameLength + 1) + " " + RSet(\ID$, 7) + " $" + Str(\Salary))
        EndIf
      EndWith
    Next
    PrintN(#CRLF$ + #CRLF$ + "Press ENTER to exit"): Input()
  EndIf             
EndProcedure
 
NewList MyEmployees.Employees()
 
displayTopEarners(MyEmployees(), 3)