# Methods

# Find

Find works like filter but returns the first element found:

const linus = employees.find((emp) => emp.name === "Linus");
1

# 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);
}
1
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'];
1
2
3
4
5

Using ES6 syntax you would do:

const names = employees.map((emp) => emp.name);
1

# 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 }
];
1
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}`);
1
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}`);
1
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}`);
1
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
1
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));
1
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"
    ]
  }
]
1
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));
  }, []);
}
1
2
3
4
5

and filter:

const filter = (collection, fn) => {
  return collection.reduce((acc, item) => {
    if (fn(item)) {
      return acc.concat(item);
    }

    return acc;
  }, []);
}
1
2
3
4
5
6
7
8
9
Updated: 1/14/2019, 6:58:59 PM