Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions exercises/26-Map_filter_and_reduce/README.es.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# `26` Map, filter and reduce

Tienes una lista de estudiantes. Cada estudiante tiene un nombre y un mentor asignado. Además, tienes otros dos arrays con los nombres de los mentores y sus IDS (array ordenado). Necesitas crear nuevos arrays con cierta información extraida de estos items.

## 📝 Instructions:

1. Crea una funcón flecha `getStudentIds` que reciba un array de estudiantes y devuelva un array de IDs

2. Crea una función flecha `filterStudents` que reciba un array de estudiantes y el nombre de un profesor, y retorne un array de estudiantes filtrados por mentor

3. Crea una función flecha `countStudents` que reciba un array de estudiantes, y lo reduzca a un objeto. Las llaves del objeto serán los ids de los mentores, y cada propiedad del objeto debe incluir el numero de estudiantes asignados al mentor (como `count`), y un texto que incluya este numero - 'Total students: x' (as `textCount`)

Example:
```
{
'456': { count: 3, textCount: 'Total students: 3' },
'457': { count: 1, textCount: 'Total students: 1' }
}
```

## 💻 Resultado esperado:

```text
['123', '124', '125', '126']
[{
id: '124',
name: 'Juan',
mentor: '457'
}]
{
'456': 'Total students: 3',
'457': 'Total students: 1',
}

```

## 💡 Pistas:

+ Recuerda usar spread operators y deconstruction

+ Puedes usar template literals para construir strings con variables
s
42 changes: 42 additions & 0 deletions exercises/26-Map_filter_and_reduce/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# `26` Map, filter and reduce

You are working with a list of students. Each student has a name and a mentor assigned. You also have two other arrays with the mentors names and Ids (sorted). You need to create some new arrays with information obtained from these items.

## 📝 Instructions:

1. Create an arrow function `getStudentIds` to receive an array of students and return an array of students IDs.

2. Create an arrow function `filterStudents` to receive an array of students and a teachers name, and then return an array of students filtered by mentor

3. Create an arrow function `countStudents` to receive an array of students, and reduce it to a single object. The object keys are the teachers ids, and each item should include the number of students assigned to the mentor (as `count`), and a parsed text including this count (as `textCount`)

Example:
```
{
'456': { count: 3, textCount: 'Total students: 3' },
'457': { count: 1, textCount: 'Total students: 1' }
}
```

## 💻 Expected Output:

```text
['123', '124', '125', '126']
[{
id: '124',
name: 'Juan',
mentor: '457'
}]
{
'456': 'Total students: 3',
'457': 'Total students: 1',
}

```

## 💡 Hints:

+ Remember to use use spread operators and deconstruction

+ You can use template literals to construct strings with dynamic values
s
36 changes: 36 additions & 0 deletions exercises/26-Map_filter_and_reduce/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
const teachersList = [
'Jose',
'Alejandro'
]
const teachersIds = [
'456', // For teacher Jose
'457' // For teacher alejandro
]

const studentsList = [
{
id: '123',
name: 'Pedro',
mentor: '456'
},
{
id: '124',
name: 'Juan',
mentor: '457'
},
{
id: '125',
name: 'Adrian',
mentor: '456'
},
{
id: '126',
name: 'Sonia',
mentor: '456'
},
]

// Don't change these variables
const studentsIDs = getStudentIds(studentsList)
const alejandroStudents = filterStudents(studentsList, 'Alejandro')
const mentorCount = countStudents(studentsList)
71 changes: 71 additions & 0 deletions exercises/26-Map_filter_and_reduce/solution.hide.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
const teachersList = [
'Jose',
'Alejandro'
]
const teachersIds = [
'456', // For teacher Jose
'457' // For teacher alejandro
]

const getStudentIds = (arr) => {
return arr.map((item) => item.id)
}

const filterStudents = (arr, teacherName) => {
const [_, alejandro] = teachersList
const [joseId, alejandroId] = teachersIds
const filterId = teacherName === alejandro ? alejandroId : joseId
// let filterId = null
// const [jose, alejandro] = teachersList
// const [joseId, alejandroId] = teachersIds
// switch(teacherName) {
// case jose:
// filterId = joseId
// break;
// case alejandro:
// filterId = alejandroId
// break;
// }
return arr.filter((item) => item.mentor === filterId)
}

const countStudents = (arr) => {
return arr.reduce((prev, curr) => {
const curCount = prev?.[curr.mentor]?.count ?? 0
return {
...prev,
[curr.mentor]: {
count: curCount + 1,
textCount: `Total students: ${curCount + 1}`
}
}
}, {})
}

const studentsList = [
{
id: '123',
name: 'Pedro',
mentor: '456'
},
{
id: '124',
name: 'Juan',
mentor: '457'
},
{
id: '125',
name: 'Adrian',
mentor: '456'
},
{
id: '126',
name: 'Sonia',
mentor: '456'
},
]

// Don't change these variables
const studentsIDs = getStudentIds(studentsList)
const alejandroStudents = filterStudents(studentsList, 'Alejandro')
const mentorCount = countStudents(studentsList)
47 changes: 47 additions & 0 deletions exercises/26-Map_filter_and_reduce/test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
const fs = require('fs');
const path = require('path');
const rewire = require("rewire");

let _buffer = '';
global.console.log = console.log = jest.fn((text) => _buffer += text + "\n");

const file = rewire("./app.js");
const studentsIDs = file.__get__("studentsIDs");
const alejandroStudents = file.__get__("alejandroStudents");
const mentorCount = file.__get__("mentorCount");

test("The function named getStudentIds should exist", function(){
const file = rewire("./app.js");
const myFunc = file.__get__('getStudentIds');
expect(myFunc).toBeTruthy();
});

test("The function named filterStudents should exist", function(){
const file = rewire("./app.js");
const myFunc = file.__get__('filterStudents');
expect(myFunc).toBeTruthy();
});

test("The function named countStudents should exist", function(){
const file = rewire("./app.js");
const myFunc = file.__get__('countStudents');
expect(myFunc).toBeTruthy();
});

test('Check studentsIDs', function () {
//You can also compare the entire console buffer (if there have been several console.log calls on the exercise)
expect(studentsIDs).toStrictEqual([ '123', '124', '125', '126' ]);
});

test('Check alejandroStudents', function () {
//You can also compare the entire console buffer (if there have been several console.log calls on the exercise)
expect(alejandroStudents).toEqual([ { id: '124', name: 'Juan', mentor: '457' } ]);
});

test('Check mentorCount', function () {
//You can also compare the entire console buffer (if there have been several console.log calls on the exercise)
expect(mentorCount).toEqual({
'456': { count: 3, textCount: 'Total students: 3' },
'457': { count: 1, textCount: 'Total students: 1' }
});
});
38 changes: 38 additions & 0 deletions exercises/27-Promises_and_arrays/README.es.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# `27` Promises and arrays

Tienes una lista de IDs de estudiantes. Necesitas crear una función para obtener información de acuerdo a cada ID (en una operacion asíncrona), asi que necesitas crear un array de Promesas para manejar todas las peticiones y ejecutar algo en base al resultado

## 📝 Instructions:

1. Crea una función flecha `mockEndpointCall` para 'mockear' la petición. Esta debe ser una función asíncrona que reciba dos parámetros: la lista de usuarios y un array de IDs bloqueados. La función debe retornar una nueva Promesa que "rechace" la operacion si es que el ID pasado se encuentra dentro de los IDs bloqueados. Si se rechaza, se debe usar el mensaje 'User is blocked', de lo contrario debe resolverse la operación con el mensaje 'User is available'

```
await mockEndpointCall(3, [1, 2]) // resolves with message "User is available"
await mockEndpointCall(1, [1, 2]) // rejects with message "User is blocked"
```

2. Crea una función flecha llamada `checkAllUsers`. Esta función recibe un arreglo de identificadores de usuario (user ids) y un arreglo de identificadores bloqueados (blocked ids).
La función debe devolver un arreglo de Promesas (por cada elemento, se usa el user id para llamar a `mockEndpointCall` y devolver el resultado).

3. Tienes tres variables llamadas “check” (checkA, checkB y checkC).
Para cada una, agrega código que cumpla con lo siguiente:

- En caso de que todos los elementos se resuelvan correctamente, imprime en la consola el mensaje:
Success: {nombre del check}'.
Ejemplo para checkA: "Success: checkA".

- En caso de que uno o más elementos fallen (sean rechazados), imprime en la consola el mensaje:
'Error: {nombre del check}'.
Ejemplo para checkA: "Error: checkA".

## 💻 Resultado Esperado:

```text
Success: checkA
Success: checkB
Error: checkC
```

## 💡 Pistas:

+ Puedes usar Promise.all para manejar el resultado de un array de Promesas
29 changes: 29 additions & 0 deletions exercises/27-Promises_and_arrays/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# `27` Promises and arrays

You have a list of students ID. You need to create a function to fetch some data based on each ID (async operation), so you want to create a list of Promises to handle all requests, and do something based on the result of all operations (resolved or rejected)
## 📝 Instructions:

1. Create an arrow function `mockEndpointCall` to "mock" the request call. This should be an async function with two parameters: the list of users, and an array of blocked ids. The function should return a new Promise that rejects if the userId is in the list of blocked Ids (with the message 'User is blocked'), else it should resolve with the message 'User is available'

```
await mockEndpointCall(3, [1, 2]) // resolves with message "User is available"
await mockEndpointCall(1, [1, 2]) // rejects with message "User is blocked"
```

2. Create an arrow function `checkAllUsers`. This function receives an array of user ids, and an array of blocked ids. The function should return an array of Promises (for each item, we use the user id to call `mockEndpointCall` and returns the result).

3. You have three "check" variables (checkA, checkB and checkC). For each one, add code to support the following:
- In case all items are resolved, print this message to the console: 'Success: {Check name}'. Example for checkA: "Sucess: checkA"
- In case one (or more) item fails (is rejected), print this message to the console: 'Error: {Check name}'. Example for checkA: "Error: checkA"

## 💻 Expected Output:

```text
Success: checkA
Success: checkB
Error: checkC
```

## 💡 Hints:

+ You can use Promise.all to catch the resolution or rejection of an array of promises
10 changes: 10 additions & 0 deletions exercises/27-Promises_and_arrays/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// List of user Ids
const studentsIds = [4560, 4561, 4562, 4563, 4564, 4565, 4566, 4567, 4568, 4569, 4570]

// your code goes here

const checkA = checkAllUsers(studentsIds, [])
const checkB = checkAllUsers(studentsIds, [123])
const checkC = checkAllUsers(studentsIds, [4561, 4565])

// Handle the promises here
28 changes: 28 additions & 0 deletions exercises/27-Promises_and_arrays/solution.hide.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// List of user Ids
const studentsIds = [4560, 4561, 4562, 4563, 4564, 4565, 4566, 4567, 4568, 4569, 4570]

// your code goes here
const mockEndpointCall = async (userId, blockedSet) => new Promise((resolve, reject) => {
if (blockedSet.has(userId)) {
reject('User is blocked')
return
}
resolve('User is available')
})

const checkAllUsers = (users, blockedUsers) => {
const blockedIdsSet = new Set(blockedUsers)
return users.map(async (item) => {
const checkStatus = await mockEndpointCall(item, blockedIdsSet)
return checkStatus
})
}

const checkA = checkAllUsers(studentsIds, [])
const checkB = checkAllUsers(studentsIds, [123])
const checkC = checkAllUsers(studentsIds, [4561, 4565])

// Handle the promises here
Promise.all(checkA).then(() => console.log('Success: checkA'))
Promise.all(checkB).then(() => console.log('Success: checkB'))
Promise.all(checkC).catch(() => console.log('Error: checkC'))
37 changes: 37 additions & 0 deletions exercises/27-Promises_and_arrays/test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
const fs = require('fs');
const path = require('path');
const rewire = require("rewire");

let _buffer = '';
global.console.log = console.log = jest.fn((text) => _buffer += text + "\n");

const file = rewire("./app.js");

test("The function named mockEndpointCall should exist", function(){
const file = rewire("./app.js");
const myFunc = file.__get__('mockEndpointCall');
expect(myFunc).toBeTruthy();
});

test("The function named checkAllUsers should exist", function(){
const file = rewire("./app.js");
const myFunc = file.__get__('checkAllUsers');
expect(myFunc).toBeTruthy();
});

const forceDelay = () => new Promise((resolve) => {
setTimeout(() => resolve(), 1000)
})

test('console.log() function should have been called 3 times', async function () {
const file = require("./app.js");
await forceDelay()
expect(console.log.mock.calls.length).toBe(3);
});

test('Check for logs after Promise resolved or rejected', async function () {
expect(_buffer.includes("Success: checkA\n")).toBe(true);
expect(_buffer.includes("Success: checkB\n")).toBe(true);
expect(_buffer.includes("Success: checkC\n")).toBe(false);
expect(_buffer.includes("Error: checkC\n")).toBe(true);
});