Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@vcpablo
Created May 12, 2021 20:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vcpablo/5dcb575c14d5008866bcd57efdd981cc to your computer and use it in GitHub Desktop.
Save vcpablo/5dcb575c14d5008866bcd57efdd981cc to your computer and use it in GitHub Desktop.
JS - from procedural to functional
const developers = [
{
id: 1,
name: 'John Doe',
age: 29,
sex: 'male',
level: 'senior',
earnings: [
{
month: 'February',
year: 2021,
amount: 12500
},
{
month: 'March',
year: 2021,
amount: 12000
},
{
month: 'April',
year: 2021,
amount: 13100
}
]
},
{
id: 2,
name: 'Peter Johnson',
age: 27,
sex: 'male',
level: 'mid',
earnings: [
{
month: 'February',
year: 2021,
amount: 9800
},
{
month: 'March',
year: 2021,
amount: 8600
},
{
month: 'April',
year: 2021,
amount: 10000
}
]
},
{
id: 3,
name: 'Jane Doe',
age: 22,
sex: 'female',
level: 'mid',
earnings: [
{
month: 'February',
year: 2021,
amount: 10450
},
{
month: 'March',
year: 2021,
amount: 11340
},
{
month: 'April',
year: 2021,
amount: 11050
}
]
},
{
id: 4,
name: 'Mary Jane',
age: 35,
sex: 'female',
level: 'senior',
earnings: [
{
month: 'February',
year: 2021,
amount: 14600
},
{
month: 'March',
year: 2021,
amount: 15230
},
{
month: 'April',
year: 2021,
amount: 14200
}
]
},
{
id: 5,
name: 'Bob Taylor',
age: 19,
sex: 'male',
level: 'junior',
earnings: [
{
month: 'February',
year: 2021,
amount: 6700
},
{
month: 'March',
year: 2021,
amount: 5900
},
{
month: 'April',
year: 2021,
amount: 6230
}
]
},
{
id: 6,
name: 'Ted Talker',
age: 48,
sex: 'male',
level: 'senior',
earnings: [
{
month: 'February',
year: 2021,
amount: 18450
},
{
month: 'March',
year: 2021,
amount: 17660
},
{
month: 'April',
year: 2021,
amount: 17995
}
]
}
]
// Procedural (imperative - requires lodash/fp)
const JUNIOR_AVERAGE_SALARY = 7000
const MID_AVERAGE_SALARY = 10000
const SENIOR_AVERAGE_SALARY = 13000
for(let developer of developers) {
let lastThreeMonthsTotalEarnings = 0
for(let earning of developer.earnings) {
lastThreeMonthsTotalEarnings += earning.amount
}
developer.averageSalary = lastThreeMonthsTotalEarnings / developer.earnings.length
if(developer.level === 'junior') {
if(developer.averageSalary === JUNIOR_AVERAGE_SALARY) {
developer.averagePosition = 'equal'
} else if(developer.averageSalary > JUNIOR_AVERAGE_SALARY) {
developer.averagePosition = 'above'
} else {
developer.averagePosition = 'below'
}
}
if(developer.level === 'mid') {
if(developer.averageSalary === MID_AVERAGE_SALARY) {
developer.averagePosition = 'equal'
} else if(developer.averageSalary > MID_AVERAGE_SALARY) {
developer.averagePosition = 'above'
} else {
developer.averagePosition = 'below'
}
}
if(developer.level === 'senior') {
if(developer.averageSalary === SENIOR_AVERAGE_SALARY) {
developer.averagePosition = 'equal'
} else if(developer.averageSalary > SENIOR_AVERAGE_SALARY) {
developer.averagePosition = 'above'
} else {
developer.averagePosition = 'below'
}
}
}
// Functiona (declarative)
import { pipe, get, reduce, map, curry } from 'lodash/fp'
const AVERAGE_SALARIES = {
junior: 7000,
mid: 10000,
senior: 13000
}
const AVERAGE_POSITIONS = {
equal: 'equal',
above: 'above',
below: 'below'
}
function appendSalaryInfo(developers) {
return pipe(
map(developer => pipe(
appendAverageSalary,
appendAveragePosition,
)(developer))
)(developers)
}
function getAveragePosition(developer) {
const { averageSalary, level } = developer
const averageSalaryReference = get(level, AVERAGE_SALARIES)
if(averageSalary === averageSalaryReference) {
return AVERAGE_POSITIONS.equal
} else if(averageSalary > averageSalaryReference) {
return AVERAGE_POSITIONS.above
} else {
return AVERAGE_POSITIONS.below
}
}
function calculateAverageSalary(developer) {
const earnings = get('earnings', developer)
return pipe(
reduce((result, { amount }) => result += amount, 0),
curry(calculateAverage)(earnings.length)
)(earnings)
}
function calculateAverage(length, total) {
return total / length
}
function appendAverageSalary(developer) {
const averageSalary = calculateAverageSalary(developer)
return {
...developer,
averageSalary
}
}
function appendAveragePosition(developer) {
const averagePosition = getAveragePosition(developer)
return {
...developer,
averagePosition
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment