# Methods
# Find
Find works like filter but returns the first element found:
const linus = employees.find((emp) => emp.name === "Linus");
# Map
The map function is used for returning a tranformed version of the original array's content. The iterator function expects you to return a new/transformed value on each iteration of the original array. The resulting array will have the same number of items but will typically contain different values.
Traditionally you would create a new list like this:
var names = [];
for (var i = 0; i < employees.length; i++) {
names.push(employees[i].name);
}
2
3
4
Using the map funtion you could do:
const employees = [{ name: 'LuKa', title: 'Programmer' }, { name: 'Juha': title: 'Manager' }];
const names = employees.map(function (emp) {
return emp.name;
});
console.log(employees); // => ['LuKa', 'Juha'];
2
3
4
5
Using ES6 syntax you would do:
const names = employees.map((emp) => emp.name);
# Reduce
The swiss army knife of list transformations. You could use it to implement some of the more specialized list functions presented above.
Let's say we have a list of orders and want a total of the amount.
const orders = [
{ amount: 250 },
{ amount: 400 },
{ amount: 100 },
{ amount: 325 }
];
2
3
4
5
6
Using a traditional approach we would use a loop:
var totalAmount = 0;
for (var i = 0; i < orders.length; i++) {
totalAmount += orders[i].amount;
}
console.log(`Total = ${totalAmount}`);
2
3
4
5
Using the reduce function we could do:
const totalAmount = employees.reduce(function (sum, order) {
return sum += order.amount;
}, 0);
console.log(`Total = ${totalAmount}`);
2
3
4
where the last param (0) is the starting value for the sum param.
Using more modern syntax it becomes a one-liner:
const totalAmount = employees.reduce((sum, order) => sum += order.amount, 0);
console.log(`Total = ${totalAmount}`);
2
# A more complex example
We have a .csv file with the following data:
Linus;Manager
Linus;Programmer
Linus;Architect
Hese;Programmer
Juha;Manager
Juha;Programmer
LuKa;Programmer
Ossi;Programmer
Eetu;Programmer
2
3
4
5
6
7
8
9
and we want to construct an array of objects containing the employee name and a list of positions the employee is holding:
const fs = require("fs");
const data = fs.readFileSync("csvdata.csv", "utf8")
.trim()
.split("\r\n")
.map(line => line.split(";"))
.reduce((employees, line) => {
let emp = employees.find((emp) => emp.name === line[0]);
if (emp) {
emp.positions.push(line[1]);
} else {
emp = {
name: line[0],
positions: [ line[1] ]
};
employees.push(emp);
}
return employees;
}, []);
console.log("data:\n", JSON.stringify(data, null, 2));
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
It would produce the following output:
data:
[
{
"name": "Linus",
"positions": [
"Manager",
"Programmer",
"Architect"
]
},
{
"name": "Hese",
"positions": [
"Programmer"
]
},
{
"name": "Juha",
"positions": [
"Manager",
"Programmer"
]
},
{
"name": "LuKa",
"positions": [
"Programmer"
]
},
{
"name": "Ossi",
"positions": [
"Programmer"
]
},
{
"name": "Eetu",
"positions": [
"Programmer"
]
}
]
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
We could implement a map() function using reduce() like this:
const map = (collection, fn) => {
return collection.reduce((acc, item) => {
return acc.concat(fn(item));
}, []);
}
2
3
4
5
and filter:
const filter = (collection, fn) => {
return collection.reduce((acc, item) => {
if (fn(item)) {
return acc.concat(item);
}
return acc;
}, []);
}
2
3
4
5
6
7
8
9