Refactoring imperative to functional
Pros of functional programming
- Readibility
- Adds an abstraction
- Easy way to compose and chain
- Avoid side effects
- Easier testing
Cons of functional programming
- Performance
- State handling
A simple example
```js
const altLabels = ['Logo France Bleu', 'Logo France Culture', 'Logo FIP']
const themes = ['news', 'culture', 'music']
const projects = [
{
name: 'France Bleu',
link: 'https://www.francebleu.fr/',
},
{
name: 'France Culture',
link: 'https://www.franceculture.fr/',
},
{
name: 'FIP',
link: 'https://www.fip.fr/',
},
]
```
The imperative way
```js
const addProjectInfo = () => {
for (let i = 0; i < projects.length; i++) {
projects[i].altLabel = altLabels[i]
projects[i].theme = themes[i]
}
}
addProjectInfo()
```
The functional way
```js
const addProjectInfo = (projectsList, altLabelsList, themesList) => {
return projectsList.map((project, index) => {
const extraValues = {
altLabel: altLabelsList[index],
theme: themesList[index],
}
return {
...project,
...extraValues
};
})
}
const result = addProjectInfo(projects, altLabels, themes)
```
Result
```js
[
{
name: 'France Bleu',
link: 'https://www.francebleu.fr/',
altLabel: 'Logo France Bleu',
theme: 'news',
},
{
name: 'France Culture',
link: 'https://www.franceculture.fr/',
altLabel: 'Logo France Culture',
theme: 'culture',
},
{
name: 'FIP',
link: 'https://www.fip.fr/',
altLabel: 'Logo FIP',
theme: 'music',
},
]
```
Another example
```js
const notesList = [
{
title: "Buy milk and bread",
createdAt: '2020-04-04',
dueDate: null,
archived: false,
},
{
title: "Pick up package at mail office",
createdAt: '2020-04-04',
dueDate: null,
archived: false,
},
{
title: "Take a walk with Yoda",
createdAt: '2020-04-04',
dueDate: null,
archived: true,
},
{
title: "Read 15 minutes",
createdAt: '2020-03-07',
dueDate: '2020-03-08',
archived: false,
},
{
title: "Do 30 minutes workout",
createdAt: '2020-03-01',
dueDate: '2020-03-04',
archived: false,
},
]
```
Lodash
```js
import _ from "lodash"
_.chain(notesList) // Lancer un chaînage lodash
.filter(['archived', false]) // Filtrer par notes non archivées
.sortBy('createdAt') // Trier par date de création
.groupBy(n => n.dueDate ? 'reminders' : 'notes') // Grouper par type
.pick(['title', 'createdAt', 'dueDate']) // Ne garder que quelques proprietés
.value() // Récupérer la valeur après chaînage
```
Lodash/fp
```js
import { filter, sortBy, groupBy, pick, compose } from "lodash/fp"
const filterNotes = filter(['archived', false]); // Filtrer par notes non archivées
const sortByCreatedAt = sortBy('createdAt'); // Trier par date de création
const groupByType = groupBy(n => n.dueDate ? 'reminders' : 'notes') // Grouper par type
const pickImportantFields = pick('title', 'createdAt', 'dueDate'); // Ne garder que quelques proprietés
const filterByType = compose(groupByType, sortByCreatedAt) // Filtrer par type
const sortedNotes = compose(
pickImportantFields,
filterByType,
filterNotes
)
sortedNotes(notesList)
```
Result
```js
{
"notes": [
{
"createdAt": "2020-04-04",
"dueDate": null,
"title": "Buy milk and bread"
},
{
"createdAt": "2020-04-04",
"dueDate": null,
"title": "Pick up package at mail office"
}
],
"reminders": [
{
"createdAt": "2020-03-01",
"dueDate": "2020-03-04",
"title": "Do 30 minutes workout"
},
{
"createdAt": "2020-03-07",
"dueDate": "2020-03-08",
"title": "Read 15 minutes"
}
]
}
```