From 3a0a7def0e042d895a45be5fa9ea425d4eb14f38 Mon Sep 17 00:00:00 2001 From: Rein Op 't Land Date: Wed, 1 May 2019 23:43:09 +0200 Subject: [PATCH 01/12] Revert "Remove solution code, add test scripts" --- 1.map-filter-find.js | 20 ++++++++++++ 1.map-filter-find.test.js | 5 --- 2.reduce.js | 62 ++++++++++++++++++++++++++++++++++++ 3.data-mining.js | 66 ++++++++++++++++++++++++++++++++++++--- 3.data-mining.test.js | 7 ----- Readme.md | 41 ------------------------ package.json | 29 ++++++++--------- 7 files changed, 157 insertions(+), 73 deletions(-) delete mode 100644 Readme.md diff --git a/1.map-filter-find.js b/1.map-filter-find.js index 8b374c2..28f4af2 100644 --- a/1.map-filter-find.js +++ b/1.map-filter-find.js @@ -3,10 +3,30 @@ const getPokeNames = (pokemons) => { } const getPokemonById = (pokemons, id) => { + return pokemons.find(pokemon => pokemon.id === id) +} + +const getRarePokemons = (pokemons) => { + return pokemons.filter(pokemon => pokemon.spawn_chance < 0.10) +} + +const getMidSizedPokemon = (pokemons) => { + return pokemons.find(pokemon => pokemon.weight === "38.0 kg") +} + +const getAdultPokemons = (pokemons) => { + return pokemons.filter(pokemon => pokemon.egg === "Not in Eggs") +} +const getPokemonImages = (pokemons) => { + return pokemons.map(pokemon => pokemon.img) } module.exports = { getPokeNames, getPokemonById, + getRarePokemons, + getMidSizedPokemon, + getAdultPokemons, + getPokemonImages } \ No newline at end of file diff --git a/1.map-filter-find.test.js b/1.map-filter-find.test.js index 49b0b35..346db7c 100644 --- a/1.map-filter-find.test.js +++ b/1.map-filter-find.test.js @@ -11,11 +11,6 @@ test('getPokeNames: Transforms an array of pokemons into an array of pokemon nam test('getPokemonById: Gets a pokemon object by their id', () => { const id = 25 const pokemon = getPokemonById(pokemons, id) - expect(pokemon).toEqual(expect.objectContaining({ - id: expect.any(Number), - name: expect.any(String), - height: expect.any(String), - })) expect(pokemon.id).toBe(25) expect(pokemon.name).toBe('Pikachu') expect(pokemon.height).toBe('0.41 m') diff --git a/2.reduce.js b/2.reduce.js index da39414..9d84640 100644 --- a/2.reduce.js +++ b/2.reduce.js @@ -5,10 +5,72 @@ const calculateTotalPokemonWeight = (pokemons) => { } const calculateAverageSpawnChance = (pokemons) => { + const totalPokemonCount = pokemons.length + const averageSpawnChance = pokemons.reduce((totalSpawnChance, currentPokemon) => { + return totalSpawnChance + currentPokemon.spawn_chance + }, 0) / totalPokemonCount + return averageSpawnChance +} + +const calculateTotalEggDistance = (pokemons) => { + return pokemons.reduce((totalDistance, currentPokemon) => { + if (currentPokemon.egg === "Not in Eggs") { + return totalDistance + } + + return totalDistance + parseInt(currentPokemon.egg) + }, 0) +} + +// Alternate solution using ternary operator +// const calculateTotalEggDistance = (pokemons) => { +// return pokemons.reduce((totalDistance, currentPokemon) => { +// const distance = currentPokemon.egg === "Not in Eggs" ? 0 : parseInt(currentPokemon.egg) +// return totalDistance + distance +// }, 0) +// } + +const getHeaviestPokemon = (pokemons) => { + return pokemons.reduce((heaviestSoFar, currentPokemon) => { + if (parseInt(heaviestSoFar.weight) > parseInt(currentPokemon.weight)) { + return heaviestSoFar + } + + return currentPokemon + }) +} + +const categorizePokemonsByRarity = (pokemons) => { + const RARE_SPAWN_CHANCE = 0.1 + const LEGENDARY_SPAWN_CHANCE = 0.01 + + const initialAccumulator = { + common: [], + rare: [], + legendary: [] + } + + return pokemons.reduce((categories, currentPokemon) => { + if (currentPokemon.spawn_chance > RARE_SPAWN_CHANCE) { + categories.common.push(currentPokemon) + return categories + } + + if (currentPokemon.spawn_chance > LEGENDARY_SPAWN_CHANCE) { + categories.rare.push(currentPokemon) + return categories + } + + categories.legendary.push(currentPokemon) + return categories + }, initialAccumulator) } module.exports = { calculateTotalPokemonWeight, calculateAverageSpawnChance, + calculateTotalEggDistance, + getHeaviestPokemon, + categorizePokemonsByRarity } \ No newline at end of file diff --git a/3.data-mining.js b/3.data-mining.js index 4716592..63ace87 100644 --- a/3.data-mining.js +++ b/3.data-mining.js @@ -1,21 +1,79 @@ -const getGymLeader = (gym, trainers) => { +const { getPokemonById } = require('./1.map-filter-find') +const { categorizePokemonsByRarity } = require('./2.reduce') +const getGymLeader = (gym, trainers) => { + return trainers.find(trainer => trainer.id === gym.trainerId) } - const getTrainerPokemons = (trainer, pokemons) => { - + return trainer.pokemonIds.map(id => { + return getPokemonById(pokemons, id) + }) } const getTrainersPokemons = (trainers, pokemons) => { - + return trainers.map(trainer => { + const trainerPokemons = getTrainerPokemons(trainer, pokemons) + return { + id: trainer.id, + name: trainer.name, + pokemons: trainerPokemons + } + }) } + +// Multi step solution: +// +// const getBigGyms = (gyms, trainers) => { +// return gyms +// .map(gym => { +// return { +// id: gym.id, +// city: gym.city, +// gymLeader: getGymLeader(gym, trainers) +// } +// }) +// .filter(gym => { +// return gym.gymLeader.pokemonIds.length > 3 +// }) +// .map(gym => gym.city) +// } + const getBigGyms = (gyms, trainers) => { + return gyms.reduce((bigGymNames, currentGym) => { + const gymLeader = getGymLeader(currentGym, trainers) + + if (gymLeader.pokemonIds.length > 3) { + bigGymNames.push(currentGym.city) + return bigGymNames + } + return bigGymNames + }, []) } const getRarestGym = (gyms, trainers, pokemons) => { + return gyms + .map(gym => { + const gymLeader = getGymLeader(gym, trainers) + const trainerPokemons = getTrainerPokemons(gymLeader, pokemons) + + return { + gym, + pokemonsByRarity: categorizePokemonsByRarity(trainerPokemons) + } + }) + .reduce((rarestGymSoFar, currentGym) => { + const legendaryCountRarestSoFar = rarestGymSoFar.pokemonsByRarity.legendary.length + const legendaryCountCurrentGym = currentGym.pokemonsByRarity.legendary.length + + if (legendaryCountCurrentGym > legendaryCountRarestSoFar) { + return currentGym + } + return rarestGymSoFar + }) + .gym } module.exports = { diff --git a/3.data-mining.test.js b/3.data-mining.test.js index 9ada6c9..8a5d88a 100644 --- a/3.data-mining.test.js +++ b/3.data-mining.test.js @@ -13,11 +13,6 @@ const { test('getGymleader: gets the gymleader belonging to a gym', () => { const fuchsiaCity = gyms.find(gym => gym.city === 'Fuchsia City') const gymLeader = getGymLeader(fuchsiaCity, trainers) - expect(gymLeader).toEqual(expect.objectContaining({ - id: expect.any(Number), - name: expect.any(String), - pokemonIds: expect.any(Array) - })) expect(gymLeader.name).toBe('Koga') }) @@ -35,8 +30,6 @@ test(`getTrainersPokemons: replaces trainerIds with the pokemons belonging to a trainer for an array of trainers`, () => { const trainersWithPokemons = getTrainersPokemons(trainers, pokemons) - expect(trainersWithPokemons).toEqual(expect.any(Array)) - trainersWithPokemons.forEach(trainer => { expect(trainer).toEqual(expect.objectContaining({ id: expect.any(Number), diff --git a/Readme.md b/Readme.md deleted file mode 100644 index e79f3fd..0000000 --- a/Readme.md +++ /dev/null @@ -1,41 +0,0 @@ -# Data transformation exercises - -## Today we practice & expand upon: map, filter, reduce, find - -Because we in JavaScript we often have to deal with array's of object. Use map, filter, reduce in find: - - -![](https://media.giphy.com/media/iz0gAwkJzWg8g/giphy.gif) - -## This repo has exercises with tests - -- There are test files set up that check the functionality of the functions you have to write. -- Test files end with .test.js, write your code in the corresponding js. file. -- 1.map-filter-find.js are exercise recap simple map, filter and find. Choose the appropriate method for each function. -- 2.reduce.js are exercises that recap reduce and expand on more powerful ways to use it (it's super effective!). -- 3.data-mining.js are exercises where you have to combine different pieces of data, (gyms, trainers and pokemon) to get the information you need. That can mean nesting maps & find or chaining array methods together in a multi-step process. - - -## How to do these exercises: - -```bash -# Clone the repo -git clone git@github.com:Codaisseur/dataTransFormationExercises.git -# Install dependencies -npm install -# Run the exercises -# 1.) -npm run exercise1 -# 2.) -npm run exercise2 -# 3.) -npm run exercise3 -# all -npm run test -``` - -Running the exercises this way will make use of the `--watch` functionality of jest. - -- That means that when you change your code, the tests will be run again (It's super ef.. well you get the idea). -- To stop running the tests you can press `ctrl + c` - diff --git a/package.json b/package.json index 04a5cdc..7fdedc5 100644 --- a/package.json +++ b/package.json @@ -1,17 +1,14 @@ { - "name": "data-transformations", - "version": "1.0.0", - "description": "A set of exercises for the data transformation day", - "main": "index.js", - "scripts": { - "test": "jest --watch", - "exercise1": "jest 1.map-filter-find.test --watch", - "exercise2": "jest 2.reduce.test --watch", - "exercise3": "jest 3.data-mining.test --watch" - }, - "author": "Codaisseur", - "license": "ISC", - "devDependencies": { - "jest": "^24.7.1" - } -} \ No newline at end of file + "name": "data-transformations", + "version": "1.0.0", + "description": "A set of exercises for the data transformation day", + "main": "index.js", + "scripts": { + "test": "jest --watch" + }, + "author": "Codaisseur", + "license": "ISC", + "devDependencies": { + "jest": "^24.7.1" + } +} From 457a4259f07065f41332d419d558d58b87bd64a4 Mon Sep 17 00:00:00 2001 From: reinoptland Date: Tue, 28 May 2019 22:05:58 +0200 Subject: [PATCH 02/12] Improve solution for getTrainerPokemons --- 3.data-mining.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/3.data-mining.js b/3.data-mining.js index 63ace87..02bb7cf 100644 --- a/3.data-mining.js +++ b/3.data-mining.js @@ -5,9 +5,7 @@ const getGymLeader = (gym, trainers) => { return trainers.find(trainer => trainer.id === gym.trainerId) } const getTrainerPokemons = (trainer, pokemons) => { - return trainer.pokemonIds.map(id => { - return getPokemonById(pokemons, id) - }) + return pokemons.filter(pokemon => trainer.pokemonIds.includes(pokemon.id)) } const getTrainersPokemons = (trainers, pokemons) => { From ea71846d7249f6d6fc1c20a02b136ed8f63e892a Mon Sep 17 00:00:00 2001 From: Billy Vlachos Date: Thu, 6 Jun 2019 14:15:40 +0200 Subject: [PATCH 03/12] Added first test --- 4.student-exercises.js | 1 + 4.student-exercises.test.js | 26 ++++++++++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 4.student-exercises.js create mode 100644 4.student-exercises.test.js diff --git a/4.student-exercises.js b/4.student-exercises.js new file mode 100644 index 0000000..2fcc285 --- /dev/null +++ b/4.student-exercises.js @@ -0,0 +1 @@ +const getNextEvolution = pokemon => {}; diff --git a/4.student-exercises.test.js b/4.student-exercises.test.js new file mode 100644 index 0000000..6e26f47 --- /dev/null +++ b/4.student-exercises.test.js @@ -0,0 +1,26 @@ +const pokemons = require("./pokeData"); +const trainers = require("./trainerData"); +const gyms = require("./gymData"); + +const { getNextEvolution } = require("./4.student-exercises"); + +test("expect next evolution", () => { + const blastoise = pokemons.find(p => p.name === "Blastoise"); + var evolution = getNextEvolution(blastoise); + expect(evolution).toEqual( + expect.objectContaining({ + id: expect.any(Number), + name: expect.toEqual("Squirtle"), + num: expect.any(String), + type: expect.any(Array) + }) + ); +}); + +// test("expect evolve", () => { +// // Provide a list of pokemons to be evolved +// }); + +// test("expect ...", () => { +// // List of gyms that have psychic pokemons +// }); From 903730af94b48b08872115755862bd776146d4ad Mon Sep 17 00:00:00 2001 From: Billy Vlachos Date: Thu, 6 Jun 2019 15:08:31 +0200 Subject: [PATCH 04/12] Added test and implementation of getPsychicTrainersAndGyms --- 4.student-exercises.js | 27 ++++++++++++++++++++++++++- 4.student-exercises.test.js | 35 +++++++++++++++-------------------- package.json | 3 ++- 3 files changed, 43 insertions(+), 22 deletions(-) diff --git a/4.student-exercises.js b/4.student-exercises.js index 2fcc285..55eaea7 100644 --- a/4.student-exercises.js +++ b/4.student-exercises.js @@ -1 +1,26 @@ -const getNextEvolution = pokemon => {}; +const getPsychicTrainersAndGyms = (gyms, trainers, pokemons) => { + // Step 1: Combine trainers and psychic pokemons + let trainersWithPsychicPokemons = trainers + // Map trainers to include their pokemons + .map(trainer => { + trainer.pokemons = pokemons.filter(pokemon => + trainer.pokemonIds.includes(pokemon.id) + ); + return trainer; + }) + // Filter the resulted trainer and return only the ones + // that actually have at least one psychic pokemon + .filter(trainer => + trainer.pokemons.some(pokemon => pokemon.type.includes("Psychic")) + ); + // Retrieve the gyms of these trainers + return trainersWithPsychicPokemons.map(trainer => { + // Assign the gym to the trainer + trainer.gym = gyms.find(gym => gym.trainerId === trainer.id); + return trainer; + }); +}; + +module.exports = { + getPsychicTrainersAndGyms +}; diff --git a/4.student-exercises.test.js b/4.student-exercises.test.js index 6e26f47..d46c048 100644 --- a/4.student-exercises.test.js +++ b/4.student-exercises.test.js @@ -2,25 +2,20 @@ const pokemons = require("./pokeData"); const trainers = require("./trainerData"); const gyms = require("./gymData"); -const { getNextEvolution } = require("./4.student-exercises"); +const { getPsychicTrainersAndGyms } = require("./4.student-exercises"); -test("expect next evolution", () => { - const blastoise = pokemons.find(p => p.name === "Blastoise"); - var evolution = getNextEvolution(blastoise); - expect(evolution).toEqual( - expect.objectContaining({ - id: expect.any(Number), - name: expect.toEqual("Squirtle"), - num: expect.any(String), - type: expect.any(Array) - }) - ); +test(`getPsychicTrainersAndGyms: expect a list of trainers with psychic pokemons. + also include (all) their pokemons and their gym`, () => { + const result = getPsychicTrainersAndGyms(gyms, trainers, pokemons); + expect(result.length).toEqual(2); + expect(result[0].name).toBe("Sabrina"); + expect(result[1].name).toBe("Misty"); + // Results should also contain gym + expect(result[0].gym).toEqual(expect.any(Object)); + expect(result[1].gym).toEqual(expect.any(Object)); + // Results should also contain array of pokemons + expect(result[0].pokemons).toEqual(expect.any(Array)); + expect(result[1].pokemons).toEqual(expect.any(Array)); + expect(result[0].pokemons.length).toBe(4); + expect(result[1].pokemons.length).toBe(2); }); - -// test("expect evolve", () => { -// // Provide a list of pokemons to be evolved -// }); - -// test("expect ...", () => { -// // List of gyms that have psychic pokemons -// }); diff --git a/package.json b/package.json index 7fdedc5..2437586 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,8 @@ "description": "A set of exercises for the data transformation day", "main": "index.js", "scripts": { - "test": "jest --watch" + "test": "jest --watch", + "exercise": "jest 4.student-exercises.test --watch" }, "author": "Codaisseur", "license": "ISC", From 250ad519aa01831b93724ff6f5ac7386f063beec Mon Sep 17 00:00:00 2001 From: Billy Vlachos Date: Thu, 6 Jun 2019 15:12:25 +0200 Subject: [PATCH 05/12] Included additional expect to test for gym city names --- 4.student-exercises.test.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/4.student-exercises.test.js b/4.student-exercises.test.js index d46c048..e74e3f1 100644 --- a/4.student-exercises.test.js +++ b/4.student-exercises.test.js @@ -4,6 +4,11 @@ const gyms = require("./gymData"); const { getPsychicTrainersAndGyms } = require("./4.student-exercises"); +/** + * This function should return an array of trainers that have + * at least one psychic pokemon. In each trainer object an array + * of their own pokemons and an object representing their gym should exist + */ test(`getPsychicTrainersAndGyms: expect a list of trainers with psychic pokemons. also include (all) their pokemons and their gym`, () => { const result = getPsychicTrainersAndGyms(gyms, trainers, pokemons); @@ -13,6 +18,8 @@ test(`getPsychicTrainersAndGyms: expect a list of trainers with psychic pokemons // Results should also contain gym expect(result[0].gym).toEqual(expect.any(Object)); expect(result[1].gym).toEqual(expect.any(Object)); + expect(result[0].gym.city).toBe("Saffron City"); + expect(result[1].gym.city).toBe("Cerulean City"); // Results should also contain array of pokemons expect(result[0].pokemons).toEqual(expect.any(Array)); expect(result[1].pokemons).toEqual(expect.any(Array)); From 4c0a99043cba103049d257ee3675e7f5298cadf9 Mon Sep 17 00:00:00 2001 From: Billy Vlachos Date: Thu, 6 Jun 2019 15:23:06 +0200 Subject: [PATCH 06/12] Added new exercise --- 4.student-exercises.js | 7 +++++++ 4.student-exercises.test.js | 21 +++++++++++++++++++++ package.json | 33 +++++++++++++++++---------------- 3 files changed, 45 insertions(+), 16 deletions(-) create mode 100644 4.student-exercises.js create mode 100644 4.student-exercises.test.js diff --git a/4.student-exercises.js b/4.student-exercises.js new file mode 100644 index 0000000..d6d071c --- /dev/null +++ b/4.student-exercises.js @@ -0,0 +1,7 @@ +const getPsychicTrainersAndGyms = (gyms, trainers, pokemons) => { + // Add your code here +}; + +module.exports = { + getPsychicTrainersAndGyms +}; diff --git a/4.student-exercises.test.js b/4.student-exercises.test.js new file mode 100644 index 0000000..9f5aec1 --- /dev/null +++ b/4.student-exercises.test.js @@ -0,0 +1,21 @@ +const pokemons = require("./pokeData"); +const trainers = require("./trainerData"); +const gyms = require("./gymData"); + +const { getPsychicTrainersAndGyms } = require("./4.student-exercises"); + +test(`getPsychicTrainersAndGyms: expect a list of trainers with psychic pokemons. + also include (all) their pokemons and their gym`, () => { + const result = getPsychicTrainersAndGyms(gyms, trainers, pokemons); + expect(result.length).toEqual(2); + expect(result[0].name).toBe("Sabrina"); + expect(result[1].name).toBe("Misty"); + expect(result[0].gym).toEqual(expect.any(Object)); + expect(result[1].gym).toEqual(expect.any(Object)); + expect(result[0].gym.city).toBe("Saffron City"); + expect(result[1].gym.city).toBe("Cerulean City"); + expect(result[0].pokemons).toEqual(expect.any(Array)); + expect(result[1].pokemons).toEqual(expect.any(Array)); + expect(result[0].pokemons.length).toBe(4); + expect(result[1].pokemons.length).toBe(2); +}); diff --git a/package.json b/package.json index 04a5cdc..5b5eb8f 100644 --- a/package.json +++ b/package.json @@ -1,17 +1,18 @@ { - "name": "data-transformations", - "version": "1.0.0", - "description": "A set of exercises for the data transformation day", - "main": "index.js", - "scripts": { - "test": "jest --watch", - "exercise1": "jest 1.map-filter-find.test --watch", - "exercise2": "jest 2.reduce.test --watch", - "exercise3": "jest 3.data-mining.test --watch" - }, - "author": "Codaisseur", - "license": "ISC", - "devDependencies": { - "jest": "^24.7.1" - } -} \ No newline at end of file + "name": "data-transformations", + "version": "1.0.0", + "description": "A set of exercises for the data transformation day", + "main": "index.js", + "scripts": { + "test": "jest --watch", + "exercise1": "jest 1.map-filter-find.test --watch", + "exercise2": "jest 2.reduce.test --watch", + "exercise3": "jest 3.data-mining.test --watch", + "exercise4": "jest 4.student-exercises.test --watch" + }, + "author": "Codaisseur", + "license": "ISC", + "devDependencies": { + "jest": "^24.7.1" + } +} From 29df8deb39c16cd6ac7661ef1a5bf6ce3858b08d Mon Sep 17 00:00:00 2001 From: Billy Vlachos Date: Thu, 6 Jun 2019 16:05:02 +0200 Subject: [PATCH 07/12] Added new test and solution to concatenate trainers gyms and pokemons --- 4.student-exercises.js | 20 +++++++++++++++++++- 4.student-exercises.test.js | 23 ++++++++++++++++++++++- 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/4.student-exercises.js b/4.student-exercises.js index 55eaea7..891853f 100644 --- a/4.student-exercises.js +++ b/4.student-exercises.js @@ -1,3 +1,20 @@ +const getTrainersAndGymsAndPokemons = (gyms, trainers, pokemons) => { + // Combine trainers and pokemons and gyms + return ( + trainers + // Map trainers to include their pokemons + .map(trainer => { + // Include the trainer's pokemons + trainer.pokemons = pokemons.filter(pokemon => + trainer.pokemonIds.includes(pokemon.id) + ); + // Include the trainer's gym + trainer.gym = gyms.filter(gym => gym.trainerId === trainer.id); + return trainer; + }) + ); +}; + const getPsychicTrainersAndGyms = (gyms, trainers, pokemons) => { // Step 1: Combine trainers and psychic pokemons let trainersWithPsychicPokemons = trainers @@ -22,5 +39,6 @@ const getPsychicTrainersAndGyms = (gyms, trainers, pokemons) => { }; module.exports = { - getPsychicTrainersAndGyms + getPsychicTrainersAndGyms, + getTrainersAndGymsAndPokemons }; diff --git a/4.student-exercises.test.js b/4.student-exercises.test.js index e74e3f1..88065d9 100644 --- a/4.student-exercises.test.js +++ b/4.student-exercises.test.js @@ -2,7 +2,28 @@ const pokemons = require("./pokeData"); const trainers = require("./trainerData"); const gyms = require("./gymData"); -const { getPsychicTrainersAndGyms } = require("./4.student-exercises"); +const { + getPsychicTrainersAndGyms, + getTrainersAndGymsAndPokemons +} = require("./4.student-exercises"); + +test("getTrainersAndGymsAndPokemons", () => { + // Get an array of trainers that contain their gyms and pokemons + const trainersAndGymsAndPokemons = getTrainersAndGymsAndPokemons( + gyms, + trainers, + pokemons + ); + expect(trainersAndGymsAndPokemons.length).toBe(9); + // Expect each trainer to have a gym object + expect(trainersAndGymsAndPokemons.map(trainer => trainer.gym)).toEqual( + expect.any(Object) + ); + // Expect each trainer to have a pokemon array + expect(trainersAndGymsAndPokemons.map(trainer => trainer.pokemons)).toEqual( + expect.any(Array) + ); +}); /** * This function should return an array of trainers that have From 0288db371b34afed397be226f987d7a75f390573 Mon Sep 17 00:00:00 2001 From: Billy Vlachos Date: Thu, 6 Jun 2019 16:13:04 +0200 Subject: [PATCH 08/12] Adjusted getPsychicTrainersAndGyms function to use newly added function --- 4.student-exercises.js | 30 +++++++++--------------------- 1 file changed, 9 insertions(+), 21 deletions(-) diff --git a/4.student-exercises.js b/4.student-exercises.js index 891853f..71b1d49 100644 --- a/4.student-exercises.js +++ b/4.student-exercises.js @@ -9,33 +9,21 @@ const getTrainersAndGymsAndPokemons = (gyms, trainers, pokemons) => { trainer.pokemonIds.includes(pokemon.id) ); // Include the trainer's gym - trainer.gym = gyms.filter(gym => gym.trainerId === trainer.id); + trainer.gym = gyms.find(gym => gym.trainerId === trainer.id); return trainer; }) ); }; const getPsychicTrainersAndGyms = (gyms, trainers, pokemons) => { - // Step 1: Combine trainers and psychic pokemons - let trainersWithPsychicPokemons = trainers - // Map trainers to include their pokemons - .map(trainer => { - trainer.pokemons = pokemons.filter(pokemon => - trainer.pokemonIds.includes(pokemon.id) - ); - return trainer; - }) - // Filter the resulted trainer and return only the ones - // that actually have at least one psychic pokemon - .filter(trainer => - trainer.pokemons.some(pokemon => pokemon.type.includes("Psychic")) - ); - // Retrieve the gyms of these trainers - return trainersWithPsychicPokemons.map(trainer => { - // Assign the gym to the trainer - trainer.gym = gyms.find(gym => gym.trainerId === trainer.id); - return trainer; - }); + return ( + // Step 1: Combine the trainers, gyms and pokemons + getTrainersAndGymsAndPokemons(gyms, trainers, pokemons) + // Step 2: Filter out only trainers that have a psychic pokemon + .filter(trainer => + trainer.pokemons.some(pokemon => pokemon.type.includes("Psychic")) + ) + ); }; module.exports = { From d5b8975afb7db2d45c4c8572047d3f1130f6fee2 Mon Sep 17 00:00:00 2001 From: Billy Vlachos Date: Thu, 6 Jun 2019 16:31:50 +0200 Subject: [PATCH 09/12] Fixed Celadon City by removing empty space after the city --- gymData.js | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/gymData.js b/gymData.js index 2bda417..887fdf7 100644 --- a/gymData.js +++ b/gymData.js @@ -1,10 +1,10 @@ module.exports = [ - { id: 1, city: 'Saffron City', trainerId: 2 }, - { id: 2, city: 'Fuchsia City', trainerId: 3 }, - { id: 3, city: 'Cinnabar Island', trainerId: 5 }, - { id: 4, city: 'Celadon City ', trainerId: 7 }, - { id: 5, city: 'Cerulean City', trainerId: 8 }, - { id: 6, city: 'Vermilion City', trainerId: 6 }, - { id: 7, city: 'Pewter City', trainerId: 1 }, - { id: 8, city: 'Viridian City', trainerId: 4 }, -] \ No newline at end of file + { id: 1, city: "Saffron City", trainerId: 2 }, + { id: 2, city: "Fuchsia City", trainerId: 3 }, + { id: 3, city: "Cinnabar Island", trainerId: 5 }, + { id: 4, city: "Celadon City", trainerId: 7 }, + { id: 5, city: "Cerulean City", trainerId: 8 }, + { id: 6, city: "Vermilion City", trainerId: 6 }, + { id: 7, city: "Pewter City", trainerId: 1 }, + { id: 8, city: "Viridian City", trainerId: 4 } +]; From 93ce5b0351e9a39dd4714d324ed9357ea4182fed Mon Sep 17 00:00:00 2001 From: Billy Vlachos Date: Thu, 6 Jun 2019 16:50:34 +0200 Subject: [PATCH 10/12] Added pokemon id 44 to Brock trainer to have variety of data for next test --- trainerData.js | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/trainerData.js b/trainerData.js index bf27fd2..152bb1d 100644 --- a/trainerData.js +++ b/trainerData.js @@ -1,11 +1,11 @@ module.exports = [ - { id: 1, name: 'Brock', pokemonIds: [74, 95] }, - { id: 2, name: 'Sabrina', pokemonIds: [64, 122, 49, 65] }, - { id: 3, name: 'Koga', pokemonIds: [109, 110, 109, 89] }, - { id: 4, name: 'Giovanni', pokemonIds: [112, 51, 31, 34, 113] }, - { id: 5, name: 'Blaine', pokemonIds: [58, 77, 78, 59] }, - { id: 6, name: 'Lt. Surge', pokemonIds: [100, 25, 26] }, - { id: 7, name: 'Erika', pokemonIds: [71, 114, 44] }, - { id: 8, name: 'Misty', pokemonIds: [120, 121] }, - { id: 9, name: 'Ash', pokemonIds: [25, 1, 7, 6, 17, 12] }, -] \ No newline at end of file + { id: 1, name: "Brock", pokemonIds: [74, 95, 44] }, + { id: 2, name: "Sabrina", pokemonIds: [64, 122, 49, 65] }, + { id: 3, name: "Koga", pokemonIds: [109, 110, 109, 89] }, + { id: 4, name: "Giovanni", pokemonIds: [112, 51, 31, 34, 113] }, + { id: 5, name: "Blaine", pokemonIds: [58, 77, 78, 59] }, + { id: 6, name: "Lt. Surge", pokemonIds: [100, 25, 26] }, + { id: 7, name: "Erika", pokemonIds: [71, 114, 44] }, + { id: 8, name: "Misty", pokemonIds: [120, 121] }, + { id: 9, name: "Ash", pokemonIds: [25, 1, 7, 6, 17, 12] } +]; From 181eaa51f29e59f2474b6411c4bf01121c04dfa8 Mon Sep 17 00:00:00 2001 From: Billy Vlachos Date: Thu, 6 Jun 2019 17:22:41 +0200 Subject: [PATCH 11/12] Included test and solution for getting gyms with certain pokemons --- 4.student-exercises.js | 38 +++++++++++++++++++++++++++++- 4.student-exercises.test.js | 47 ++++++++++++++++++++++++++++++++++++- 2 files changed, 83 insertions(+), 2 deletions(-) diff --git a/4.student-exercises.js b/4.student-exercises.js index 71b1d49..a3f0745 100644 --- a/4.student-exercises.js +++ b/4.student-exercises.js @@ -26,7 +26,43 @@ const getPsychicTrainersAndGyms = (gyms, trainers, pokemons) => { ); }; +const getGymsWithPokemons = (gyms, trainers, pokemons, ...pokemonsToFind) => { + // Retrieve the pokemon objects + return ( + pokemons + // Filter all the pokemons based on the ones we requested to find + .filter(pokemon => pokemonsToFind.includes(pokemon.name)) + .map(pokemon => { + // Construct the object to be returned + return { + id: pokemon.id, + name: pokemon.name, + // Retrieve the trainers that own this pokemon + trainers: trainers.filter(trainer => + trainer.pokemonIds.includes(pokemon.id) + ), + // Retrieve the gyms that are owned by these trainers + gyms: gyms.filter(gym => { + return trainers + .filter(trainer => trainer.pokemonIds.includes(pokemon.id)) + .find(trainer => trainer.id === gym.trainerId); + }) + }; + }) + ); + + return getTrainersAndGymsAndPokemons(gyms, trainers, pokemons) + .filter(trainer => + trainer.pokemons.some(pokemon => pokemonsToFind.includes(pokemon.name)) + ) + .map(trainer => { + return {}; + trainer.gym; + }); +}; + module.exports = { getPsychicTrainersAndGyms, - getTrainersAndGymsAndPokemons + getTrainersAndGymsAndPokemons, + getGymsWithPokemons }; diff --git a/4.student-exercises.test.js b/4.student-exercises.test.js index 88065d9..d39deca 100644 --- a/4.student-exercises.test.js +++ b/4.student-exercises.test.js @@ -4,9 +4,14 @@ const gyms = require("./gymData"); const { getPsychicTrainersAndGyms, - getTrainersAndGymsAndPokemons + getTrainersAndGymsAndPokemons, + getGymsWithPokemons } = require("./4.student-exercises"); +/** + * This function should return an array of trainer objects + * that also include an array of pokemons and an object of gym + */ test("getTrainersAndGymsAndPokemons", () => { // Get an array of trainers that contain their gyms and pokemons const trainersAndGymsAndPokemons = getTrainersAndGymsAndPokemons( @@ -47,3 +52,43 @@ test(`getPsychicTrainersAndGyms: expect a list of trainers with psychic pokemons expect(result[0].pokemons.length).toBe(4); expect(result[1].pokemons.length).toBe(2); }); + +/** + * Returns an array of objects with the id and name of pokemon and an array + * of gym objects where these pokemons can be found. + */ +test("getGymsWithPokemons: expect a list of gyms where certain pokemons can be found", () => { + const result = getGymsWithPokemons( + gyms, + trainers, + pokemons, + "Gloom", + "Starmie" + ); + // Expect the result to be an array + result.forEach(pokemon => { + // It is an array of pokemons + expect(pokemon).toEqual( + expect.objectContaining({ + id: expect.any(Number), + name: expect.any(String), + trainers: expect.any(Array), // Should contain a list of trainers + gyms: expect.any(Array) // Should contain a list of gyms + }) + ); + }); + // Length of array should be 2 + expect(result.length).toEqual(2); + // Check owners + expect(result[0].trainers.length).toEqual(2); + expect(result[1].trainers.length).toEqual(1); + expect(result[0].trainers[0].name).toBe("Brock"); + expect(result[0].trainers[1].name).toBe("Erika"); + expect(result[1].trainers[0].name).toBe("Misty"); + // Check Gyms + expect(result[0].gyms.length).toEqual(2); + expect(result[1].gyms.length).toEqual(1); + expect(result[0].gyms[0].city).toBe("Celadon City"); + expect(result[0].gyms[1].city).toBe("Pewter City"); + expect(result[1].gyms[0].city).toBe("Cerulean City"); +}); From 769cd84c332f3602fefd477aa83db068133a9f72 Mon Sep 17 00:00:00 2001 From: Billy Vlachos Date: Thu, 6 Jun 2019 17:41:30 +0200 Subject: [PATCH 12/12] Removed comments and solutions --- 4.student-exercises.js | 55 ++----------------------------------- 4.student-exercises.test.js | 27 ++---------------- package.json | 2 +- 3 files changed, 5 insertions(+), 79 deletions(-) diff --git a/4.student-exercises.js b/4.student-exercises.js index a3f0745..4fc34bc 100644 --- a/4.student-exercises.js +++ b/4.student-exercises.js @@ -1,64 +1,13 @@ const getTrainersAndGymsAndPokemons = (gyms, trainers, pokemons) => { - // Combine trainers and pokemons and gyms - return ( - trainers - // Map trainers to include their pokemons - .map(trainer => { - // Include the trainer's pokemons - trainer.pokemons = pokemons.filter(pokemon => - trainer.pokemonIds.includes(pokemon.id) - ); - // Include the trainer's gym - trainer.gym = gyms.find(gym => gym.trainerId === trainer.id); - return trainer; - }) - ); + }; const getPsychicTrainersAndGyms = (gyms, trainers, pokemons) => { - return ( - // Step 1: Combine the trainers, gyms and pokemons - getTrainersAndGymsAndPokemons(gyms, trainers, pokemons) - // Step 2: Filter out only trainers that have a psychic pokemon - .filter(trainer => - trainer.pokemons.some(pokemon => pokemon.type.includes("Psychic")) - ) - ); + }; const getGymsWithPokemons = (gyms, trainers, pokemons, ...pokemonsToFind) => { - // Retrieve the pokemon objects - return ( - pokemons - // Filter all the pokemons based on the ones we requested to find - .filter(pokemon => pokemonsToFind.includes(pokemon.name)) - .map(pokemon => { - // Construct the object to be returned - return { - id: pokemon.id, - name: pokemon.name, - // Retrieve the trainers that own this pokemon - trainers: trainers.filter(trainer => - trainer.pokemonIds.includes(pokemon.id) - ), - // Retrieve the gyms that are owned by these trainers - gyms: gyms.filter(gym => { - return trainers - .filter(trainer => trainer.pokemonIds.includes(pokemon.id)) - .find(trainer => trainer.id === gym.trainerId); - }) - }; - }) - ); - return getTrainersAndGymsAndPokemons(gyms, trainers, pokemons) - .filter(trainer => - trainer.pokemons.some(pokemon => pokemonsToFind.includes(pokemon.name)) - ) - .map(trainer => { - return {}; - trainer.gym; - }); }; module.exports = { diff --git a/4.student-exercises.test.js b/4.student-exercises.test.js index d39deca..1d233b4 100644 --- a/4.student-exercises.test.js +++ b/4.student-exercises.test.js @@ -8,55 +8,37 @@ const { getGymsWithPokemons } = require("./4.student-exercises"); -/** - * This function should return an array of trainer objects - * that also include an array of pokemons and an object of gym - */ test("getTrainersAndGymsAndPokemons", () => { - // Get an array of trainers that contain their gyms and pokemons const trainersAndGymsAndPokemons = getTrainersAndGymsAndPokemons( gyms, trainers, pokemons ); expect(trainersAndGymsAndPokemons.length).toBe(9); - // Expect each trainer to have a gym object expect(trainersAndGymsAndPokemons.map(trainer => trainer.gym)).toEqual( expect.any(Object) ); - // Expect each trainer to have a pokemon array expect(trainersAndGymsAndPokemons.map(trainer => trainer.pokemons)).toEqual( expect.any(Array) ); }); -/** - * This function should return an array of trainers that have - * at least one psychic pokemon. In each trainer object an array - * of their own pokemons and an object representing their gym should exist - */ test(`getPsychicTrainersAndGyms: expect a list of trainers with psychic pokemons. also include (all) their pokemons and their gym`, () => { const result = getPsychicTrainersAndGyms(gyms, trainers, pokemons); expect(result.length).toEqual(2); expect(result[0].name).toBe("Sabrina"); expect(result[1].name).toBe("Misty"); - // Results should also contain gym expect(result[0].gym).toEqual(expect.any(Object)); expect(result[1].gym).toEqual(expect.any(Object)); expect(result[0].gym.city).toBe("Saffron City"); expect(result[1].gym.city).toBe("Cerulean City"); - // Results should also contain array of pokemons expect(result[0].pokemons).toEqual(expect.any(Array)); expect(result[1].pokemons).toEqual(expect.any(Array)); expect(result[0].pokemons.length).toBe(4); expect(result[1].pokemons.length).toBe(2); }); -/** - * Returns an array of objects with the id and name of pokemon and an array - * of gym objects where these pokemons can be found. - */ test("getGymsWithPokemons: expect a list of gyms where certain pokemons can be found", () => { const result = getGymsWithPokemons( gyms, @@ -65,27 +47,22 @@ test("getGymsWithPokemons: expect a list of gyms where certain pokemons can be f "Gloom", "Starmie" ); - // Expect the result to be an array result.forEach(pokemon => { - // It is an array of pokemons expect(pokemon).toEqual( expect.objectContaining({ id: expect.any(Number), name: expect.any(String), - trainers: expect.any(Array), // Should contain a list of trainers - gyms: expect.any(Array) // Should contain a list of gyms + trainers: expect.any(Array), + gyms: expect.any(Array) }) ); }); - // Length of array should be 2 expect(result.length).toEqual(2); - // Check owners expect(result[0].trainers.length).toEqual(2); expect(result[1].trainers.length).toEqual(1); expect(result[0].trainers[0].name).toBe("Brock"); expect(result[0].trainers[1].name).toBe("Erika"); expect(result[1].trainers[0].name).toBe("Misty"); - // Check Gyms expect(result[0].gyms.length).toEqual(2); expect(result[1].gyms.length).toEqual(1); expect(result[0].gyms[0].city).toBe("Celadon City"); diff --git a/package.json b/package.json index 2437586..0613168 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "main": "index.js", "scripts": { "test": "jest --watch", - "exercise": "jest 4.student-exercises.test --watch" + "exercise4": "jest 4.student-exercises.test --watch" }, "author": "Codaisseur", "license": "ISC",