Top rank per group: Difference between revisions

m
→‎{{header|AppleScript}}: New sort handler URL, tidy-up.
m (syntax highlighting fixup automation)
m (→‎{{header|AppleScript}}: New sort handler URL, tidy-up.)
Line 370:
It looks as if this task's requirements have changed — possibly more than once — since it was first set and named. As at the end of May 2021, it specifies the return of the top N ''salaries'' in each department and makes no mention at all of any of the other employee details. This makes it easier to decide how to handle the other thing it doesn't mention: what to return when two or more people in the same department are on the same pay. The interpretation here is "top N ''discrete'' salary values" (or of course fewer if a department doesn't have that many).
 
<syntaxhighlight lang="applescript">use AppleScript version "2.3.1" -- Mac OS X 10.9 (Mavericks) or later for these 'use' commands!.
use sorter : script ¬
use sorter : script "Custom Iterative Ternary Merge Sort" -- <https://www.macscripter.net/viewtopic.php?pid=194430#p194430t/timsort-and-nigsort/71383/3>
 
on topNSalariesPerDepartment(employeeRecords, n)
Line 377 ⟶ 378:
set employeeCount to (count employeeRecords)
if ((employeeCount > 0) and (n > 0)) then
-- Sort a copy of the employee record list by department with descending subsorts on salary.
-- with descending subsorts on salary.
copy employeeRecords to employeeRecords
script comparer
on isGreater(a, b)
return ((a's department > b's department) or ((a's department = b's department) and (a's salary < b's salary)))¬
((a's department = b's department) and (a's salary < b's salary)))
end isGreater
end script
Line 388 ⟶ 391:
end considering
-- Initialise the output with data from the first record in the sorted list, then work through the rest of the list.
-- then work through the rest of the list.
set {department:previousDepartment, salary:previousSalary} to beginning of employeeRecords
set {padValuemv, topSalaries, counter} to {missing value"-", {previousSalary}, 1}
set end of output to {department:previousDepartment, salaries:topSalaries}
repeat with i from 2 to employeeCount
set {department:thisDepartment, salary:thisSalary} to item i of employeeRecords
if (thisDepartment is= previousDepartment) then
if ((thisSalary < previousSalary) and (counter(count topSalaries) < n)) then
-- Another record from the same department. Include its salary in the output if different from
-- the previous one's and if fewer than n salaries from the department have been included so far.
if ((thisSalary < previousSalary) and (counter < n)) then
set end of topSalaries to thisSalary
set counter to counter + 1
set previousSalary to thisSalary
end if
else
-- First record of the next department.
-- Pad out the previous department's salary list with missing values if it has fewer than n entries.
repeat (n - counter(count topSalaries)) times
set end of topSalaries to padValuemv
end repeat
-- Start a result record for the new department and add it to the output.
set topSalaries to {thisSalary}
set counter to 1
set end of output to {department:thisDepartment, salaries:topSalaries}
set previousDepartment to thisDepartment
Line 417:
end repeat
-- Pad the last department's salary list if necessary.
repeat (n - counter(count topSalaries)) times
set end of topSalaries to padValuemv
end repeat
end if
Line 425:
end topNSalariesPerDepartment
 
on demojoin(lst, delim)
set astid to AppleScript's text item delimiters
set AppleScript's text item delimiters to " "delim
set reporttxt to reportlst as text
set AppleScript's text item delimiters to astid
return reporttxt
end demojoin
 
on task()
set employeeRecords to {¬
{|name|:"Tyler Bennett", |ID|:"E10297", salary:32000, department:"D101"}, ¬
Line 444 ⟶ 452:
set n to 4
set topSalaryRecords to topNSalariesPerDepartment(employeeRecords, n)
--> eg. {{department:"D050", salaries:{47000, 21900, missing value, missing value}}, … }
-- Derive a text report from the result.
set report to {"Top " & n & " salaries per department:"}
set astid to AppleScript's text item delimiters
set AppleScript's text item delimiters to " "
repeat with thisRecord in topSalaryRecords
set end of report to thisRecord's department & ": " & join(thisRecord's salaries, " ")
set i to n
repeat while (item i of thisRecord's salaries is missing value)
set item i of thisRecord's salaries to "-"
set i to i - 1
end repeat
set end of report to thisRecord's department & ": " & thisRecord's salaries
end repeat
setreturn AppleScript's text item delimiters tojoin(report, linefeed)
end task
set report to report as text
set AppleScript's text item delimiters to astid
return report
end demo
 
demotask()</syntaxhighlight>
 
{{output}}
557

edits