How to resolve the algorithm Top rank per group step by step in the Go programming language
How to resolve the algorithm Top rank per group step by step in the Go programming language
Table of Contents
Problem Statement
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:
Let's start with the solution:
Step by Step solution about How to resolve the algorithm Top rank per group step by step in the Go programming language
The code snippet you provided defines a Employee
struct that represents an employee with fields for name, ID, salary, and department.
It also defines an EmployeeList
type that is a slice of Employee
structs.
The data
variable is an EmployeeList
that contains a list of employees with their respective information.
The code then defines a By
type that is a function that takes two Employee
structs and returns a bool
indicating whether the first employee should be sorted before the second employee.
The employeeSorter
type is a custom sorter that implements the sort.Interface
interface.
It is used to sort the EmployeeList
by the specified By
function.
The TopSalariesByDept
method of the EmployeeList
type takes an integer n
and returns a slice of EmployeeList
s, one for each department.
Each EmployeeList
contains the top n
employees in the department, sorted by salary in descending order.
If there are ties for the n
th salary, all employees with that salary are included in the list.
The main
function calls the TopSalariesByDept
method of the data
EmployeeList
with n
set to 3 and stores the result in the top
variable.
If the top
slice is empty, it prints "Nothing to show." and returns.
Otherwise, it prints "Top 3 salaries per department" and iterates over the top
slice, printing the department name and the ID, name, and salary of each employee in the department.
Source code in the go programming language
package main
import (
"fmt"
"sort"
)
// language-native data description
type Employee struct {
Name, ID string
Salary int
Dept string
}
type EmployeeList []*Employee
var data = EmployeeList{
{"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"},
// Extra data to demonstrate ties
{"Tie A", "E16399", 29900, "D190"},
{"Tie B", "E16400", 29900, "D190"},
{"No Tie", "E16401", 29899, "D190"},
}
// We only need one type of ordering/grouping for this task so we could directly
// implement sort.Interface on EmployeeList (or a byDeptSalary alias type) with
// the appropriate Less method.
//
// Instead, we'll add a bit here that makes it easier to use arbitrary orderings.
// This is like the "SortKeys" Planet sorting example in the sort package
// documentation, see https://golang.org/pkg/sort
type By func(e1, e2 *Employee) bool
type employeeSorter struct {
list EmployeeList
by func(e1, e2 *Employee) bool
}
func (by By) Sort(list EmployeeList) { sort.Sort(&employeeSorter{list, by}) }
func (s *employeeSorter) Len() int { return len(s.list) }
func (s *employeeSorter) Swap(i, j int) { s.list[i], s.list[j] = s.list[j], s.list[i] }
func (s *employeeSorter) Less(i, j int) bool { return s.by(s.list[i], s.list[j]) }
// For this specific task we could just write the data to an io.Writer
// but in general it's better to return the data in a usable form (for
// example, perhaps other code want's to do something like compare the
// averages of the top N by department).
//
// So we go through the extra effort of returning an []EmployeeList, a
// list of employee lists, one per deparment. The lists are trimmed to
// to the top 'n', which can be larger than n if there are ties for the
// nth salary (callers that don't care about ties could just trim more.)
func (el EmployeeList) TopSalariesByDept(n int) []EmployeeList {
if n <= 0 || len(el) == 0 {
return nil
}
deptSalary := func(e1, e2 *Employee) bool {
if e1.Dept != e2.Dept {
return e1.Dept < e2.Dept
}
if e1.Salary != e2.Salary {
return e1.Salary > e2.Salary
}
// Always have some unique field as the last one in a sort list
return e1.ID < e2.ID
}
// We could just sort the data in place for this task. But
// perhaps messing with the order is undesirable or there is
// other concurrent access. So we'll make a copy and sort that.
// It's just pointers so the amount to copy is relatively small.
sorted := make(EmployeeList, len(el))
copy(sorted, el)
By(deptSalary).Sort(sorted)
perDept := []EmployeeList{}
var lastDept string
var lastSalary int
for _, e := range sorted {
if e.Dept != lastDept || len(perDept) == 0 {
lastDept = e.Dept
perDept = append(perDept, EmployeeList{e})
} else {
i := len(perDept) - 1
if len(perDept[i]) >= n && e.Salary != lastSalary {
continue
}
perDept[i] = append(perDept[i], e)
lastSalary = e.Salary
}
}
return perDept
}
func main() {
const n = 3
top := data.TopSalariesByDept(n)
if len(top) == 0 {
fmt.Println("Nothing to show.")
return
}
fmt.Printf("Top %d salaries per department\n", n)
for _, list := range top {
fmt.Println(list[0].Dept)
for _, e := range list {
fmt.Printf(" %s %16s %7d\n", e.ID, e.Name, e.Salary)
}
}
}
You may also check:How to resolve the algorithm Substring/Top and tail step by step in the J programming language
You may also check:How to resolve the algorithm Hilbert curve step by step in the Factor programming language
You may also check:How to resolve the algorithm Strip a set of characters from a string step by step in the Prolog programming language
You may also check:How to resolve the algorithm String append step by step in the ALGOL 68 programming language
You may also check:How to resolve the algorithm Quickselect algorithm step by step in the Raku programming language