Skip to content

Instantly share code, notes, and snippets.

@steshaw
Forked from robertpenner/employee_salaries.ts
Created August 6, 2017 08:39
Show Gist options
  • Save steshaw/c5e07e5ce49402c4d53077ec76c7c9ce to your computer and use it in GitHub Desktop.
Save steshaw/c5e07e5ce49402c4d53077ec76c7c9ce to your computer and use it in GitHub Desktop.
Employee Average Salaries | Victor Savkin's Functional TypeScript
// https://gist.githubusercontent.com/robertpenner/f02bb38553adb09ec09e2e265c01c750/raw/9f0f7bfaabebeb375e774c528bfc5089f52a80d7/employee_salaries.ts
// https://vsavkin.com/functional-typescript-316f0e003dc6
class Employee {
constructor(public name: string, public salary: number) {}
}
class Department {
constructor(public employees: Employee[]) {}
works(employee: Employee): boolean {
return this.employees.indexOf(employee) > -1
}
}
type Predicate<T> = (t: T) => boolean
function and<T>(p1 : Predicate<T>, p2: Predicate<T>) {
return (v) => p1(v) && p2(v)
}
function andAll<T>(predicates: Predicate<T>[]): Predicate<T> {
return predicates.reduce((p1, p2) => and(p1, p2), (v) => true)
}
function filteredSalaries(employees: Employee[], p: Predicate<Employee>): number[] {
return employees.filter(p).map(e => e.salary)
}
function average(nums: number[]): number {
const total = nums.reduce((a,b) => a + b, 0)
return total / nums.length
}
function averageFilteredSalary(employees: Employee[], p: Predicate<Employee>): number {
return average(filteredSalaries(employees, p))
}
const employees = [
new Employee("Jim", 100),
new Employee("John", 200),
new Employee("Liz", 120),
new Employee("Penny", 30)
]
const sales = new Department([employees[0], employees[1]])
const salaryGt50 = (employee) => employee.salary > 50
const worksForSales = (employee) => sales.works(employee)
function technique1() {
const p = andAll([salaryGt50, worksForSales])
const salesAverageSalaryOver50 = averageFilteredSalary(employees, p)
console.log('technique1: salesAverageSalaryOver50:', salesAverageSalaryOver50)
}
function technique2() {
// No need for array of predicates.
const p = and(salaryGt50, worksForSales)
const salesAverageSalaryOver50 = averageFilteredSalary(employees, p)
console.log('technique2: salesAverageSalaryOver50:', salesAverageSalaryOver50)
}
function technique3() {
// Inline the averageFilteredSalary as it was very small now.
const p = and(salaryGt50, worksForSales)
const salesAverageSalaryOver50 = average(employees.filter(p).map(e => e.salary))
console.log('technique3: salesAverageSalaryOver50:', salesAverageSalaryOver50)
}
technique1()
technique2()
technique3()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment