feat(challenges): Added math challenge stubs

This commit is contained in:
Quincy Larson
2017-08-30 17:35:35 -07:00
parent f373eca1aa
commit 0fa97530bb
356 changed files with 85679 additions and 0 deletions

View File

@@ -0,0 +1,971 @@
{
"name": "Basic Algorithm Scripting",
"order": 5,
"time": "50 hours",
"helpRoom": "HelpJavaScript",
"challenges": [
{
"id": "bd7158d2c442eddfbeb5bd1f",
"title": "Get Set for our Algorithm Challenges",
"description": [
[
"//i.imgur.com/sJkp30a.png",
"An image of a algorithm challenge showing directions, tests, and the code editor.",
"Our algorithm challenges will teach you how to think like a programmer.",
""
],
[
"//i.imgur.com/d8LuRNh.png",
"A mother bird kicks a baby bird out of her nest.",
"Our previous challenges introduced you to programming concepts. But for these algorithm challenges, you'll now need to apply what you learned to solve open-ended problems.",
""
],
[
"//i.imgur.com/WBetuBa.jpg",
"A programmer punching through his laptop screen in frustration.",
"Our algorithm challenges are hard. Some of them may take you several hours to solve. You will get frustrated. But don't quit.",
""
],
[
"//i.imgur.com/p2TpOQd.jpg",
"A cute dog jumping over a hurdle and winking and pointing his paw at you.",
"When you get stuck, just use the Read-Search-Ask methodology.<br>Don't worry - you've got this.",
""
]
],
"challengeSeed": [],
"tests": [],
"type": "Waypoint",
"challengeType": 7,
"isRequired": false,
"translations": {
"es": {
"title": "Prepárate para nuestros Desafíos sobre Algoritmos",
"description": [
[
"//i.imgur.com/sJkp30a.png",
"Una imagen de un desafio sobre algoritmos que presenta instrucciones, pruebas y el editor de código.",
"Nuestros desafios sobre algoritmos te enseñarán como pensar como un programador.",
""
],
[
"//i.imgur.com/d8LuRNh.png",
"Una mamá pájaro saca un bebé pájaro fuer de su nido.",
"Nuestros desafios anteriores te introdujeron a los conceptos de programación. Pero para estos desafios sobre algoritmos, ahora necesitarás aplicar lo que has aprendido y resolver problemas de respuesta abierta",
""
],
[
"//i.imgur.com/WBetuBa.jpg",
"Un programador frustado golpeando la pantalla de su computador.",
"Nuestros desafíos sobre algortimos son difíciles. Algunos pueden requerir muchas horas para resolverse. Podrás frustarte, pero no te rindas.",
""
],
[
"//i.imgur.com/p2TpOQd.jpg",
"Un tierno perro que salta sobre un obstáculo, pica el ojo y te apunta con su pata.",
"Cuando te atasques, usa la metodología Leer-Buscar-Preguntar.<br>No te preocupes - ya lo has entendido.",
""
]
]
},
"pt-br": {
"title": "Prepare-se para nossos desafios de algoritmos",
"description": [
[
"//i.imgur.com/sJkp30a.png",
"Uma imagem de um desafio de algoritmo mostrando instruções, testes e o editor de código.",
"Nossos desafios de algoritmos vão te ensinar a pensar como um programador.",
""
],
[
"//i.imgur.com/d8LuRNh.png",
"Uma mãe pássaro expulsa seu filhote do ninho.",
"Os desafios anteriores te apresentaram os conceitos de programação. Mas para esses desafios de algoritmos, você terá que aplicar o que aprendeu para resolver problemas abertos.",
""
],
[
"//i.imgur.com/WBetuBa.jpg",
"Um programador frustrado atravessando a tela de seu laptop com um soco.",
"Os desafios de algoritmos são difíceis. Você pode levar várias horas para resolver alguns deles. Você vai ficar frustado. Mas não desista.",
""
],
[
"//i.imgur.com/p2TpOQd.jpg",
"Um cachorro fofo pulando sobre um obstáculo, piscando e apontando a pata na sua direção.",
"Quando ficar travado, use a metodologia Ler-Pesquisar-Perguntar.<br>Não se preocupe - você consegue.",
""
]
]
}
}
},
{
"id": "56533eb9ac21ba0edf2244b3",
"title": "Convert Celsius to Fahrenheit",
"description": [
"The algorithm to convert from Celsius to Fahrenheit is the temperature in Celsius times <code>9/5</code>, plus <code>32</code>.",
"You are given a variable <code>celsius</code> representing a temperature in Celsius. Use the variable <code>fahrenheit</code> already defined and assign it the Fahrenheit temperature equivalent to the given Celsius temperature. Use the algorithm mentioned above to help convert the Celsius temperature to Fahrenheit.",
"Don't worry too much about the function and return statements as they will be covered in future challenges. For now, only use operators that you have already learned."
],
"releasedOn": "January 1, 2016",
"challengeSeed": [
"function convertToF(celsius) {",
" var fahrenheit;",
" return fahrenheit;",
"}",
"",
"convertToF(30);"
],
"solutions": [
"function convertToF(celsius) {\n var fahrenheit = celsius * 9/5 + 32;\n if ( typeof fahrenheit !== 'undefined' ) {\n return fahrenheit;\n } else {\n return 'fahrenheit not defined';\n }\n}"
],
"tests": [
"assert(typeof convertToF(0) === 'number', 'message: <code>convertToF(0)</code> should return a number');",
"assert(convertToF(-30) === -22, 'message: <code>convertToF(-30)</code> should return a value of <code>-22</code>');",
"assert(convertToF(-10) === 14, 'message: <code>convertToF(-10)</code> should return a value of <code>14</code>');",
"assert(convertToF(0) === 32, 'message: <code>convertToF(0)</code> should return a value of <code>32</code>');",
"assert(convertToF(20) === 68, 'message: <code>convertToF(20)</code> should return a value of <code>68</code>');",
"assert(convertToF(30) === 86, 'message: <code>convertToF(30)</code> should return a value of <code>86</code>');"
],
"type": "checkpoint",
"challengeType": 1,
"isRequired": true,
"translations": {
"es": {
"title": "Convierte celsius a fahrenheit",
"description": [
"Para probar tu aprendizaje, crearás una solucion \"desde cero\". Coloca tu código entre las líneas indicadas y este será probado contra multiples casos de prueba.",
"El algoritmo para convertir de Celsius a Fahrenheit consiste en multiplicar la temperatura en grados Celsius por 9/5 y al resultado agregarle 32.",
"Se te da una variable <code>celsius</code> representando una temperatura en Celsius. Crea una variable <code>fahrenheit</code> y aplica el algoritmo para asignar la correspondiente temperatura en Fahrenheit."
]
},
"pt-br": {
"title": "Converta Celsius para Fahrenheit",
"description": [
"O algoritmo para converter de Celsius para Fahrenheit é a temperatura em Celsius vezes <code>9/5</code> mais <code>32</code>.",
"Você recebe uma variável <code>celsius</code> representando uma temperatura em Celsius. Use a variável <code>fahrenheit</code> já definida e aplique o algoritmo para atribuir a ela a temperatura correspondente em Fahrenheit."
]
}
}
},
{
"id": "a202eed8fc186c8434cb6d61",
"title": "Reverse a String",
"description": [
"Reverse the provided string.",
"You may need to turn the string into an array before you can reverse it.",
"Your result must be a string.",
"Remember to use <a href=\"http://forum.freeCodeCamp.com/t/how-to-get-help-when-you-are-stuck/19514\" target=\"_blank\">Read-Search-Ask</a> if you get stuck. Write your own code."
],
"challengeSeed": [
"function reverseString(str) {",
" return str;",
"}",
"",
"reverseString(\"hello\");"
],
"tests": [
"assert(typeof reverseString(\"hello\") === \"string\", 'message: <code>reverseString(\"hello\")</code> should return a string.');",
"assert(reverseString(\"hello\") === \"olleh\", 'message: <code>reverseString(\"hello\")</code> should become <code>\"olleh\"</code>.');",
"assert(reverseString(\"Howdy\") === \"ydwoH\", 'message: <code>reverseString(\"Howdy\")</code> should become <code>\"ydwoH\"</code>.');",
"assert(reverseString(\"Greetings from Earth\") === \"htraE morf sgniteerG\", 'message: <code>reverseString(\"Greetings from Earth\")</code> should return <code>\"htraE morf sgniteerG\"</code>.');"
],
"type": "bonfire",
"isRequired": true,
"solutions": [
"function reverseString(str) {\n return str.split('').reverse().join(\"\");\n}\n\nreverseString('hello');\n"
],
"MDNlinks": [
"Global String Object",
"String.prototype.split()",
"Array.prototype.reverse()",
"Array.prototype.join()"
],
"challengeType": 5,
"translations": {
"es": {
"title": "Invierte el texto",
"description": [
"Invierte la cadena de texto que se te provee",
"Puede que necesites convertir la cadena de texto en un arreglo antes de que puedas invertirla",
"El resultado debe ser una cadena de texto",
"Recuerda utilizar <a href='http://forum.freeCodeCamp.com/t/how-to-get-help-when-you-are-stuck/19514' target='_blank'>Leer-Buscar-Preguntar</a> si te sientes atascado. Intenta programar en pareja. Escribe tu propio código."
]
},
"pt-br": {
"title": "Inverta uma string",
"description": [
"Inverta a string fornecida.",
"Talvez você tenha que transformar a string num array antes de invertê-la.",
"Seu resultado deve ser uma string.",
"Lembre-se de <a href=\"http://forum.freeCodeCamp.com/t/how-to-get-help-when-you-are-stuck/19514\" target=\"_blank\">Ler-Pesquisar-Perguntar</a> se ficar travado. Escreva seu próprio código."
]
}
}
},
{
"id": "a302f7aae1aa3152a5b413bc",
"title": "Factorialize a Number",
"description": [
"Return the factorial of the provided integer.",
"If the integer is represented with the letter n, a factorial is the product of all positive integers less than or equal to n.",
"Factorials are often represented with the shorthand notation <code>n!</code>",
"For example: <code>5! = 1 * 2 * 3 * 4 * 5 = 120</code>",
"Only integers greater than or equal to zero will be supplied to the function.",
"Remember to use <a href=\"http://forum.freeCodeCamp.com/t/how-to-get-help-when-you-are-stuck/19514\" target=\"_blank\">Read-Search-Ask</a> if you get stuck. Write your own code."
],
"challengeSeed": [
"function factorialize(num) {",
" return num;",
"}",
"",
"factorialize(5);"
],
"tests": [
"assert(typeof factorialize(5) === 'number', 'message: <code>factorialize(5)</code> should return a number.');",
"assert(factorialize(5) === 120, 'message: <code>factorialize(5)</code> should return 120.');",
"assert(factorialize(10) === 3628800, 'message: <code>factorialize(10)</code> should return 3628800.');",
"assert(factorialize(20) === 2432902008176640000, 'message: <code>factorialize(20)</code> should return 2432902008176640000.');",
"assert(factorialize(0) === 1, 'message: <code>factorialize(0)</code> should return 1.');"
],
"type": "bonfire",
"isRequired": true,
"solutions": [
"function factorialize(num) {\n return num < 1 ? 1 : num * factorialize(num-1);\n}\n\nfactorialize(5);\n"
],
"MDNlinks": [
"Arithmetic Operators"
],
"challengeType": 5,
"translations": {
"es": {
"title": "Factoriza un número",
"description": [
"Crea una función que devuelva el factorial del número entero que se te provee",
"El factorial de un número entero positivo n es la multiplicación de todos los enteros positivos menores o iguales a n",
"Los factoriales son comúnmente representados con la notación <code>n!</code>",
"Por ejemplo: <code>5! = 1 * 2 * 3 * 4 * 5 = 120</code>",
"Recuerda utilizar <a href='http://forum.freeCodeCamp.com/t/how-to-get-help-when-you-are-stuck/19514' target='_blank'>Leer-Buscar-Preguntar</a> si te sientes atascado. Intenta programar en pareja. Escribe tu propio código."
]
},
"pt-br": {
"title": "Determine o fatorial de um número",
"description": [
"Retorne o fatorial do inteiro fornecido.",
"Se o inteiro é representado pela letra n, o seu fatorial é o produto de todos os inteiros positivos menores ou iguais a n.",
"Por exemplo: <code>5! = 1 * 2 * 3 * 4 * 5 = 120</code>",
"Apenas inteiros maiores ou iguais a zero serão fornecidos à função.",
"Lembre-se de <a href=\"http://forum.freeCodeCamp.com/t/how-to-get-help-when-you-are-stuck/19514\" target=\"_blank\">Ler-Pesquisar-Perguntar</a> se ficar travado. Escreva seu próprio código."
]
}
}
},
{
"id": "a26cbbe9ad8655a977e1ceb5",
"title": "Find the Longest Word in a String",
"description": [
"Return the length of the longest word in the provided sentence.",
"Your response should be a number.",
"Remember to use <a href=\"http://forum.freeCodeCamp.com/t/how-to-get-help-when-you-are-stuck/19514\" target=\"_blank\">Read-Search-Ask</a> if you get stuck. Write your own code."
],
"challengeSeed": [
"function findLongestWordLength(str) {",
" return str.length;",
"}",
"",
"findLongestWordLength(\"The quick brown fox jumped over the lazy dog\");"
],
"tests": [
"assert(typeof findLongestWordLength(\"The quick brown fox jumped over the lazy dog\") === \"number\", 'message: <code>findLongestWordLength(\"The quick brown fox jumped over the lazy dog\")</code> should return a number.');",
"assert(findLongestWordLength(\"The quick brown fox jumped over the lazy dog\") === 6, 'message: <code>findLongestWordLength(\"The quick brown fox jumped over the lazy dog\")</code> should return 6.');",
"assert(findLongestWordLength(\"May the force be with you\") === 5, 'message: <code>findLongestWordLength(\"May the force be with you\")</code> should return 5.');",
"assert(findLongestWordLength(\"Google do a barrel roll\") === 6, 'message: <code>findLongestWordLength(\"Google do a barrel roll\")</code> should return 6.');",
"assert(findLongestWordLength(\"What is the average airspeed velocity of an unladen swallow\") === 8, 'message: <code>findLongestWordLength(\"What is the average airspeed velocity of an unladen swallow\")</code> should return 8.');",
"assert(findLongestWordLength(\"What if we try a super-long word such as otorhinolaryngology\") === 19, 'message: <code>findLongestWordLength(\"What if we try a super-long word such as otorhinolaryngology\")</code> should return 19.');"
],
"type": "bonfire",
"isRequired": true,
"solutions": [
"function findLongestWordLength(str) {\n return str.split(' ').sort(function(a, b) { return b.length - a.length;})[0].length;\n}\n\nfindLongestWordLength('The quick brown fox jumped over the lazy dog');\n"
],
"MDNlinks": [
"String.prototype.split()",
"String.length"
],
"challengeType": 5,
"translations": {
"es": {
"title": "Encuentra la palabra más larga",
"description": [
"Crea una función que devuelva la longitud de la palabra más larga en una frase dada",
"El resultado debe ser un número",
"Recuerda utilizar <a href='http://forum.freeCodeCamp.com/t/how-to-get-help-when-you-are-stuck/19514' target='_blank'>Leer-Buscar-Preguntar</a> si te sientes atascado. Intenta programar en pareja. Escribe tu propio código."
]
},
"pt-br": {
"title": "Encontre a palavra mais longa de uma string",
"description": [
"Retorne o tamanho da palavra mais longa da frase fornecida.",
"Sua resposta deve ser um número.",
"Lembre-se de <a href=\"http://forum.freeCodeCamp.com/t/how-to-get-help-when-you-are-stuck/19514\" target=\"_blank\">Ler-Pesquisar-Perguntar</a> se ficar travado. Escreva seu próprio código."
]
}
}
},
{
"id": "a789b3483989747d63b0e427",
"title": "Return Largest Numbers in Arrays",
"description": [
"Return an array consisting of the largest number from each provided sub-array. For simplicity, the provided array will contain exactly 4 sub-arrays.",
"Remember, you can iterate through an array with a simple for loop, and access each member with array syntax <code>arr[i]</code>.",
"Remember to use <a href=\"http://forum.freeCodeCamp.com/t/how-to-get-help-when-you-are-stuck/19514\" target=\"_blank\">Read-Search-Ask</a> if you get stuck. Write your own code."
],
"challengeSeed": [
"function largestOfFour(arr) {",
" // You can do this!",
" return arr;",
"}",
"",
"largestOfFour([[4, 5, 1, 3], [13, 27, 18, 26], [32, 35, 37, 39], [1000, 1001, 857, 1]]);"
],
"tests": [
"assert(largestOfFour([[4, 5, 1, 3], [13, 27, 18, 26], [32, 35, 37, 39], [1000, 1001, 857, 1]]).constructor === Array, 'message: <code>largestOfFour([[4, 5, 1, 3], [13, 27, 18, 26], [32, 35, 37, 39], [1000, 1001, 857, 1]])</code> should return an array.');",
"assert.deepEqual(largestOfFour([[13, 27, 18, 26], [4, 5, 1, 3], [32, 35, 37, 39], [1000, 1001, 857, 1]]), [27, 5, 39, 1001], 'message: <code>largestOfFour([[13, 27, 18, 26], [4, 5, 1, 3], [32, 35, 37, 39], [1000, 1001, 857, 1]])</code> should return <code>[27, 5, 39, 1001]</code>.');",
"assert.deepEqual(largestOfFour([[4, 9, 1, 3], [13, 35, 18, 26], [32, 35, 97, 39], [1000000, 1001, 857, 1]]), [9, 35, 97, 1000000], 'message: <code>largestOfFour([[4, 9, 1, 3], [13, 35, 18, 26], [32, 35, 97, 39], [1000000, 1001, 857, 1]])</code> should return <code>[9, 35, 97, 1000000]</code>.');",
"assert.deepEqual(largestOfFour([[17, 23, 25, 12], [25, 7, 34, 48], [4, -10, 18, 21], [-72, -3, -17, -10]]), [25, 48, 21, -3], 'message: <code>largestOfFour([[17, 23, 25, 12], [25, 7, 34, 48], [4, -10, 18, 21], [-72, -3, -17, -10]])</code> should return <code>[25, 48, 21, -3]</code>.');"
],
"type": "bonfire",
"isRequired": true,
"solutions": [
"function largestOfFour(arr) {\n return arr.map(function(subArr) {\n return Math.max.apply(null, subArr);\n });\n}\n\nlargestOfFour([[4, 5, 1, 3], [13, 27, 18, 26], [32, 35, 37, 39], [1000, 1001, 857, 1]]);\n"
],
"MDNlinks": [
"Comparison Operators"
],
"challengeType": 5,
"translations": {
"es": {
"title": "Devuelve el mayor entero de cada arreglo",
"description": [
"Crea una función que devuelva un arreglo que contenga el mayor de los números de cada sub-arreglo que recibe. Para simplificar las cosas, el arreglo que recibirá tendrá exactamente 4 sub-arreglos",
"Recuerda que puedes iterar a través de un arreglo con un búcle simple, y acceder a cada miembro utilizando la sintaxis arr[i].",
"Si escribes tu propio test con Chai.js, asegúrate de utilizar un operador de igualdad estricto en lugar de un operador de igualdad cuando compares arreglos. ",
"Recuerda utilizar <a href='http://forum.freeCodeCamp.com/t/how-to-get-help-when-you-are-stuck/19514' target='_blank'>Leer-Buscar-Preguntar</a> si te sientes atascado. Intenta programar en pareja. Escribe tu propio código."
]
},
"pt-br": {
"title": "Retorne os maiores números de arrays",
"description": [
"Retorne um array contendo o maior número de cada sub-array fornecido. Para simplificar, o array fornecido conterá exatamente 4 sub-arrays.",
"Lembre-se, você pode iterar por um array com um simples <code>for</code> e acessar cada membro do array com a sintaxe <code>arr[i]</code>.",
"Lembre-se de <a href=\"http://forum.freeCodeCamp.com/t/how-to-get-help-when-you-are-stuck/19514\" target=\"_blank\">Ler-Pesquisar-Perguntar</a> se ficar travado. Escreva seu próprio código."
]
}
}
},
{
"id": "acda2fb1324d9b0fa741e6b5",
"title": "Confirm the Ending",
"description": [
"Check if a string (first argument, <code>str</code>) ends with the given target string (second argument, <code>target</code>).",
"This challenge <em>can</em> be solved with the <code>.endsWith()</code> method, which was introduced in ES2015. But for the purpose of this challenge, we would like you to use one of the JavaScript substring methods instead.",
"Remember to use <a href=\"http://forum.freeCodeCamp.com/t/how-to-get-help-when-you-are-stuck/19514\" target=\"_blank\">Read-Search-Ask</a> if you get stuck. Write your own code."
],
"challengeSeed": [
"function confirmEnding(str, target) {",
" // \"Never give up and good luck will find you.\"",
" // -- Falcor",
" return str;",
"}",
"",
"confirmEnding(\"Bastian\", \"n\");"
],
"tests": [
"assert(confirmEnding(\"Bastian\", \"n\") === true, 'message: <code>confirmEnding(\"Bastian\", \"n\")</code> should return true.');",
"assert(confirmEnding(\"Congratulation\", \"on\") === true, 'message: <code>confirmEnding(\"Congratulation\", \"on\")</code> should return true.');",
"assert(confirmEnding(\"Connor\", \"n\") === false, 'message: <code>confirmEnding(\"Connor\", \"n\")</code> should return false.');",
"assert(confirmEnding(\"Walking on water and developing software from a specification are easy if both are frozen\", \"specification\") === false, 'message: <code>confirmEnding(\"Walking on water and developing software from a specification are easy if both are frozen\"&#44; \"specification\"&#41;</code> should return false.');",
"assert(confirmEnding(\"He has to give me a new name\", \"name\") === true, 'message: <code>confirmEnding(\"He has to give me a new name\", \"name\")</code> should return true.');",
"assert(confirmEnding(\"Open sesame\", \"same\") === true, 'message: <code>confirmEnding(\"Open sesame\", \"same\")</code> should return true.');",
"assert(confirmEnding(\"Open sesame\", \"pen\") === false, 'message: <code>confirmEnding(\"Open sesame\", \"pen\")</code> should return false.');",
"assert(confirmEnding(\"Open sesame\", \"game\") === false, 'message: <code>confirmEnding(\"Open sesame\", \"game\")</code> should return false.');",
"assert(confirmEnding(\"If you want to save our world, you must hurry. We dont know how much longer we can withstand the nothing\", \"mountain\") === false, 'message: <code>confirmEnding(\"If you want to save our world, you must hurry. We dont know how much longer we can withstand the nothing\", \"mountain\")</code> should return false.');",
"assert(confirmEnding(\"Abstraction\", \"action\") === true, 'message: <code>confirmEnding(\"Abstraction\", \"action\")</code> should return true.');",
"assert(!/\\.endsWith\\(.*?\\)\\s*?;?/.test(code), 'message: Do not use the built-in method <code>.endsWith()</code> to solve the challenge.');"
],
"type": "bonfire",
"isRequired": true,
"solutions": [
"function confirmEnding(str, target) {\n return str.substring(str.length-target.length) === target;\n};\n"
],
"MDNlinks": [
"String.prototype.substr()",
"String.prototype.substring()"
],
"challengeType": 5,
"translations": {
"es": {
"title": "Confirma la terminación",
"description": [
"Verifica si una cadena de texto (primer argumento) termina con otra cadena de texto (segundo argumento).",
"Recuerda utilizar <a href='http://forum.freeCodeCamp.com/t/how-to-get-help-when-you-are-stuck/19514' target='_blank'>Leer-Buscar-Preguntar</a> si te sientes atascado. Intenta programar en pareja. Escribe tu propio código."
]
},
"pt-br": {
"title": "Confirme o final",
"description": [
"Verifique se uma string (primeiro argumento, <code>str</code>) termina com a string alvo fornecida (segundo argumento, <code>target</code>).",
"Esse desafio <em>pode</em> ser resolvido com o método <code>.endsWith()</code>, que foi introduzido na ES2015. Mas para o propósito desse desafio, nós gostaríamos que, ao invés dele, você usasse algum dos métodos de substring do JavaScript.",
"Lembre-se de <a href=\"http://forum.freeCodeCamp.com/t/how-to-get-help-when-you-are-stuck/19514\" target=\"_blank\">Ler-Pesquisar-Perguntar</a> se ficar travado. Escreva seu próprio código."
]
}
}
},
{
"id": "afcc8d540bea9ea2669306b6",
"title": "Repeat a String Repeat a String",
"description": [
"Repeat a given string <code>str</code> (first argument) for <code>num</code> times (second argument). Return an empty string if <code>num</code> is not a positive number.",
"Remember to use <a href=\"http://forum.freeCodeCamp.com/t/how-to-get-help-when-you-are-stuck/19514\" target=\"_blank\">Read-Search-Ask</a> if you get stuck. Write your own code."
],
"challengeSeed": [
"function repeatStringNumTimes(str, num) {",
" // repeat after me",
" return str;",
"}",
"",
"repeatStringNumTimes(\"abc\", 3);"
],
"tests": [
"assert(repeatStringNumTimes(\"*\", 3) === \"***\", 'message: <code>repeatStringNumTimes(\"*\", 3)</code> should return <code>\"***\"</code>.');",
"assert(repeatStringNumTimes(\"abc\", 3) === \"abcabcabc\", 'message: <code>repeatStringNumTimes(\"abc\", 3)</code> should return <code>\"abcabcabc\"</code>.');",
"assert(repeatStringNumTimes(\"abc\", 4) === \"abcabcabcabc\", 'message: <code>repeatStringNumTimes(\"abc\", 4)</code> should return <code>\"abcabcabcabc\"</code>.');",
"assert(repeatStringNumTimes(\"abc\", 1) === \"abc\", 'message: <code>repeatStringNumTimes(\"abc\", 1)</code> should return <code>\"abc\"</code>.');",
"assert(repeatStringNumTimes(\"*\", 8) === \"********\", 'message: <code>repeatStringNumTimes(\"*\", 8)</code> should return <code>\"********\"</code>.');",
"assert(repeatStringNumTimes(\"abc\", -2) === \"\", 'message: <code>repeatStringNumTimes(\"abc\", -2)</code> should return <code>\"\"</code>.');",
"assert(!/\\.repeat/g.test(code), 'message: The built-in <code>repeat()</code>-method should not be used');"
],
"type": "bonfire",
"isRequired": true,
"solutions": [
"function repeatStringNumTimes(str, num) {\n if (num < 0) return '';\n return num === 1 ? str : str + repeatStringNumTimes(str, num-1);\n}\n\nrepeatStringNumTimes('abc', 3);\n"
],
"MDNlinks": [
"Global String Object"
],
"challengeType": 5,
"translations": {
"es": {
"title": "Repite el Texto Repite el Texto",
"description": [
"Repite una cadena de texto dada (primer argumento) <code>num</code> veces (segundo argumento). Retorna una cadena de texto vacía si <code>num</code> es un número negativo.",
"Recuerda utilizar <a href='http://forum.freeCodeCamp.com/t/how-to-get-help-when-you-are-stuck/19514' target='_blank'>Leer-Buscar-Preguntar</a> si te sientes atascado. Intenta programar en pareja. Escribe tu propio código."
]
},
"pt-br": {
"title": "Repita uma string Repita uma string",
"description": [
"Repita uma string <code>str</code> dada (primeiro argumento) <code>num</code> vezes (segundo argumento). Retorne uma string vazia se <code>num</code> não for um número positivo.",
"Lembre-se de <a href=\"http://forum.freeCodeCamp.com/t/how-to-get-help-when-you-are-stuck/19514\" target=\"_blank\">Ler-Pesquisar-Perguntar</a> se ficar travado. Escreva seu próprio código."
]
}
}
},
{
"id": "ac6993d51946422351508a41",
"title": "Truncate a String",
"description": [
"Truncate a string (first argument) if it is longer than the given maximum string length (second argument). Return the truncated string with a <code>...</code> ending.",
"Remember to use <a href=\"http://forum.freeCodeCamp.com/t/how-to-get-help-when-you-are-stuck/19514\" target=\"_blank\">Read-Search-Ask</a> if you get stuck. Write your own code."
],
"challengeSeed": [
"function truncateString(str, num) {",
" // Clear out that junk in your trunk",
" return str;",
"}",
"",
"truncateString(\"A-tisket a-tasket A green and yellow basket\", 8);"
],
"tests": [
"assert(truncateString(\"A-tisket a-tasket A green and yellow basket\", 8) === \"A-tisket...\", 'message: <code>truncateString(\"A-tisket a-tasket A green and yellow basket\", 8)</code> should return \"A-tisket...\".');",
"assert(truncateString(\"Peter Piper picked a peck of pickled peppers\", 11) === \"Peter Piper...\", 'message: <code>truncateString(\"Peter Piper picked a peck of pickled peppers\", 11)</code> should return \"Peter Piper...\".');",
"assert(truncateString(\"A-tisket a-tasket A green and yellow basket\", \"A-tisket a-tasket A green and yellow basket\".length) === \"A-tisket a-tasket A green and yellow basket\", 'message: <code>truncateString(\"A-tisket a-tasket A green and yellow basket\", \"A-tisket a-tasket A green and yellow basket\".length)</code> should return \"A-tisket a-tasket A green and yellow basket\".');",
"assert(truncateString('A-tisket a-tasket A green and yellow basket', 'A-tisket a-tasket A green and yellow basket'.length + 2) === 'A-tisket a-tasket A green and yellow basket', 'message: <code>truncateString(\"A-tisket a-tasket A green and yellow basket\", \"A-tisket a-tasket A green and yellow basket\".length + 2)</code> should return \"A-tisket a-tasket A green and yellow basket\".');",
"assert(truncateString(\"A-\", 1) === \"A...\", 'message: <code>truncateString(\"A-\", 1)</code> should return \"A...\".');",
"assert(truncateString(\"Absolutely Longer\", 2) === \"Ab...\", 'message: <code>truncateString(\"Absolutely Longer\", 2)</code> should return \"Ab...\".');"
],
"type": "bonfire",
"isRequired": true,
"solutions": [
"function truncateString(str, num) {\n if (num >= str.length) {\n return str;\n }\n return str.slice(0, num) + '...';\n}"
],
"MDNlinks": [
"String.prototype.slice()"
],
"challengeType": 5,
"translations": {
"es": {
"title": "Trunca una Cadena de Texto",
"description": [
"Trunca una cadena de texto (primer argumento) si su longitud es mayor que un máximo de caracteres dado (segundo argumento). Devuelve la cadena de texto truncada con una terminación \"...\".",
"Recuerda utilizar <a href='http://forum.freeCodeCamp.com/t/how-to-get-help-when-you-are-stuck/19514' target='_blank'>Leer-Buscar-Preguntar</a> si te sientes atascado. Intenta programar en pareja. Escribe tu propio código."
]
},
"pt-br": {
"title": "Trunque uma string",
"description": [
"Trunque uma string (primeiro argumento) se ela for mais longa do que o comprimento máximo dado (segundo argumento). Retorne a string truncada com um <code>...</code> no final.",
"Lembre-se de <a href=\"http://forum.freeCodeCamp.com/t/how-to-get-help-when-you-are-stuck/19514\" target=\"_blank\">Ler-Pesquisar-Perguntar</a> se ficar travado. Escreva seu próprio código."
]
}
}
},
{
"id": "a6e40f1041b06c996f7b2406",
"title": "Finders Keepers",
"description": [
"Create a function that looks through an array (first argument) and returns the first element in the array that passes a truth test (second argument). If no element passes the test, return undefined.",
"Remember to use <a href='http://forum.freeCodeCamp.com/t/how-to-get-help-when-you-are-stuck/19514' target='_blank'>Read-Search-Ask</a> if you get stuck. Try to pair program. Write your own code."
],
"challengeSeed": [
"function findElement(arr, func) {",
" var num = 0;",
" return num;",
"}",
"",
"findElement([1, 2, 3, 4], function(num){ return num % 2 === 0; });"
],
"solutions": [
"function findElement(arr, func) {\n var num;\n arr.some(function(e) {\n if (func(e)) {\n num = e;\n return true;\n }\n });\n return num;\n}"
],
"tests": [
"assert.strictEqual(findElement([1, 3, 5, 8, 9, 10], function(num) { return num % 2 === 0; }), 8, 'message: <code>findElement([1, 3, 5, 8, 9, 10], function(num) { return num % 2 === 0; })</code> should return 8.');",
"assert.strictEqual(findElement([1, 3, 5, 9], function(num) { return num % 2 === 0; }), undefined, 'message: <code>findElement([1, 3, 5, 9], function(num) { return num % 2 === 0; })</code> should return undefined.');"
],
"type": "bonfire",
"MDNlinks": [
"Array.prototype.filter()"
],
"isRequired": true,
"challengeType": 5,
"translations": {
"es": {
"title": "Buscando la verdad",
"description": [
"Crea una función que busque dentro de un vector (primer argumento) y que devuelva el primer elemento que pase una prueba de verdad (segundo argumento).",
"Recuerda utilizar <a href='http://forum.freeCodeCamp.com/t/how-to-get-help-when-you-are-stuck/19514' target='_blank'>Leer-Buscar-Preguntar</a> si te sientes atascado. Intenta programar en pareja. Escribe tu propio código."
]
},
"pt-br": {
"title": "Achado não é roubado",
"description": [
"Crie uma função que itera sobre um array (primeiro argumento) e retorna o primeiro elemento do array que retornar <code>true</code> para uma função de teste (segundo argumento). Se nenhum elemento passar no teste, retorne <code>undefined</code>.",
"Lembre-se de <a href=\"http://forum.freeCodeCamp.com/t/how-to-get-help-when-you-are-stuck/19514\" target=\"_blank\">Ler-Pesquisar-Perguntar</a> se ficar travado. Escreva seu próprio código."
]
},
"fr": {
"title": "Détecteur de mensonges",
"description": [
"Crée une fonction qui parcourt un tableau (premier argument) et renvoie le premier élément du tableau qui passe le test (second argument).",
"N'oublie pas d'utiliser <a href='http://forum.freeCodeCamp.com/t/how-to-get-help-when-you-are-stuck/19514' target='_blank'>Lire-Chercher-Demander</a> si tu es bloqué. Essaye de trouver un partenaire. Écris ton propre code."
]
}
}
},
{
"id": "a77dbc43c33f39daa4429b4f",
"title": "Boo who",
"description": [
"Check if a value is classified as a boolean primitive. Return true or false.",
"Boolean primitives are true and false.",
"Remember to use <a href='http://forum.freeCodeCamp.com/t/how-to-get-help-when-you-are-stuck/19514' target='_blank'>Read-Search-Ask</a> if you get stuck. Try to pair program. Write your own code."
],
"challengeSeed": [
"function booWho(bool) {",
" // What is the new fad diet for ghost developers? The Boolean.",
" return bool;",
"}",
"",
"booWho(null);"
],
"solutions": [
"function booWho(bool) {\n // What is the new fad diet for ghost developers? The Boolean.\n return typeof bool === \"boolean\";\n}\n\nbooWho(null);"
],
"tests": [
"assert.strictEqual(booWho(true), true, 'message: <code>booWho(true)</code> should return true.');",
"assert.strictEqual(booWho(false), true, 'message: <code>booWho(false)</code> should return true.');",
"assert.strictEqual(booWho([1, 2, 3]), false, 'message: <code>booWho([1, 2, 3])</code> should return false.');",
"assert.strictEqual(booWho([].slice), false, 'message: <code>booWho([].slice)</code> should return false.');",
"assert.strictEqual(booWho({ \"a\": 1 }), false, 'message: <code>booWho({ \"a\": 1 })</code> should return false.');",
"assert.strictEqual(booWho(1), false, 'message: <code>booWho(1)</code> should return false.');",
"assert.strictEqual(booWho(NaN), false, 'message: <code>booWho(NaN)</code> should return false.');",
"assert.strictEqual(booWho(\"a\"), false, 'message: <code>booWho(\"a\")</code> should return false.');",
"assert.strictEqual(booWho(\"true\"), false, 'message: <code>booWho(\"true\")</code> should return false.');",
"assert.strictEqual(booWho(\"false\"), false, 'message: <code>booWho(\"false\")</code> should return false.');"
],
"type": "bonfire",
"MDNlinks": [
"Boolean Objects"
],
"isRequired": true,
"challengeType": 5,
"translations": {
"es": {
"title": "¡Bu!",
"description": [
"Crea una función que verifique si el valor que se le pasa es de tipo booleano. Haz que la función devuelva true o false según corresponda.",
"Los primitivos booleanos primitivos son: true y false",
"Recuerda utilizar <a href='http://forum.freeCodeCamp.com/t/how-to-get-help-when-you-are-stuck/19514' target='_blank'>Leer-Buscar-Preguntar</a> si te sientes atascado. Intenta programar en pareja. Escribe tu propio código."
]
},
"pt-br": {
"title": "Bu!",
"description": [
"Verifique se um valor é classificado como um primitivo booleano. Retorne <code>true</code> ou <code>false</code>.",
"Primitivos booleanos são <code>true</code> e <code>false</code>.",
"Lembre-se de <a href=\"http://forum.freeCodeCamp.com/t/how-to-get-help-when-you-are-stuck/19514\" target=\"_blank\">Ler-Pesquisar-Perguntar</a> se ficar travado. Tente programar em par. Escreva seu próprio código."
]
},
"fr": {
"title": "Boo !",
"description": [
"Crée une fonction qui vérifie qu'une valeur est de type booléen. Renvoie true ou false.",
"Les primitives booléennes sont true ou false.",
"N'oublie pas d'utiliser <a href='http://forum.freeCodeCamp.com/t/how-to-get-help-when-you-are-stuck/19514' target='_blank'>Lire-Chercher-Demander</a> si tu es bloqué. Essaye de trouver un partenaire. Écris ton propre code."
]
}
}
},
{
"id": "ab6137d4e35944e21037b769",
"title": "Title Case a Sentence",
"description": [
"Return the provided string with the first letter of each word capitalized. Make sure the rest of the word is in lower case.",
"For the purpose of this exercise, you should also capitalize connecting words like \"the\" and \"of\".",
"Remember to use <a href=\"http://forum.freeCodeCamp.com/t/how-to-get-help-when-you-are-stuck/19514\" target=\"_blank\">Read-Search-Ask</a> if you get stuck. Write your own code."
],
"challengeSeed": [
"function titleCase(str) {",
" return str;",
"}",
"",
"titleCase(\"I'm a little tea pot\");"
],
"tests": [
"assert(typeof titleCase(\"I'm a little tea pot\") === \"string\", 'message: <code>titleCase(\"I&#39;m a little tea pot\")</code> should return a string.');",
"assert(titleCase(\"I'm a little tea pot\") === \"I'm A Little Tea Pot\", 'message: <code>titleCase(\"I&#39;m a little tea pot\")</code> should return <code>I&#39;m A Little Tea Pot</code>.');",
"assert(titleCase(\"sHoRt AnD sToUt\") === \"Short And Stout\", 'message: <code>titleCase(\"sHoRt AnD sToUt\")</code> should return <code>Short And Stout</code>.');",
"assert(titleCase(\"HERE IS MY HANDLE HERE IS MY SPOUT\") === \"Here Is My Handle Here Is My Spout\", 'message: <code>titleCase(\"HERE IS MY HANDLE HERE IS MY SPOUT\")</code> should return <code>Here Is My Handle Here Is My Spout</code>.');"
],
"type": "bonfire",
"isRequired": true,
"solutions": [
"function titleCase(str) {\n return str.split(' ').map(function(word) {\n return word.charAt(0).toUpperCase() + word.substring(1).toLowerCase();\n }).join(' ');\n}\n\ntitleCase(\"I'm a little tea pot\");\n"
],
"MDNlinks": [
"String.prototype.split()"
],
"challengeType": 5,
"translations": {
"es": {
"title": "Aplica formato de título",
"description": [
"Crea una función que devuelva la cadena de texto que recibe con la primera letra de cada palabra en mayúscula. Asegúrate de que el resto de las letras sean minúsculas",
"Para este ejercicio, también debes poner en mayúscula conectores como \"the\" y \"of\".",
"Recuerda utilizar <a href='http://forum.freeCodeCamp.com/t/how-to-get-help-when-you-are-stuck/19514' target='_blank'>Leer-Buscar-Preguntar</a> si te sientes atascado. Intenta programar en pareja. Escribe tu propio código."
]
},
"pt-br": {
"title": "Transforme Uma String Num Título",
"description": [
"Retorne a string fornecida com a primeira letra de cada palavra em maiúsculo. Certifique-se de que o resto da palavra esteja minúsculo.",
"Para o propósito desse exercício, você também deve deixar maiúscula a primeira letra das palavras de ligação como \"the\" e \"of\".",
"Lembre-se de <a href=\"http://forum.freeCodeCamp.com/t/how-to-get-help-when-you-are-stuck/19514\" target=\"_blank\">Ler-Pesquisar-Perguntar</a> se ficar travado. Escreva seu próprio código."
]
}
}
},
{
"id": "579e2a2c335b9d72dd32e05c",
"title": "Slice and Splice",
"description": [
"You are given two arrays and an index.",
"Use the array methods <code>slice</code> and <code>splice</code> to copy each element of the first array into the second array, in order.",
"Begin inserting elements at index <code>n</code> of the second array.",
"Return the resulting array. The input arrays should remain the same after the function runs.",
"Remember to use <a href=\"http://forum.freeCodeCamp.com/t/how-to-get-help-when-you-are-stuck/19514\" target=\"_blank\">Read-Search-Ask</a> if you get stuck. Write your own code."
],
"challengeSeed": [
"function frankenSplice(arr1, arr2, n) {",
" // It's alive. It's alive!",
" return arr2;",
"}",
"",
"frankenSplice([1, 2, 3], [4, 5, 6], 1);"
],
"tail": [
"var testArr1 = [1, 2];",
"var testArr2 = ['a', 'b'];"
],
"tests": [
"assert.deepEqual(frankenSplice([1, 2, 3], [4, 5], 1), [4, 1, 2, 3, 5], 'message: <code>frankenSplice([1, 2, 3], [4, 5], 1)</code> should return <code>[4, 1, 2, 3, 5]</code>.');",
"assert.deepEqual(frankenSplice(testArr1, testArr2, 1), ['a', 1, 2, 'b'], 'message: <code>frankenSplice([1, 2], [\"a\", \"b\"], 1)</code> should return <code>[\"a\", 1, 2, \"b\"]</code>.');",
"assert.deepEqual(frankenSplice(['claw', 'tentacle'], ['head', 'shoulders', 'knees', 'toes'], 2), ['head', 'shoulders', 'claw', 'tentacle', 'knees', 'toes'], 'message: <code>frankenSplice([\"claw\", \"tentacle\"], [\"head\", \"shoulders\", \"knees\", \"toes\"], 2)</code> should return <code>[\"head\", \"shoulders\", \"claw\", \"tentacle\", \"knees\", \"toes\"]</code>.');",
"assert.deepEqual(frankenSplice([1, 2, 3, 4], [], 0), [1, 2, 3, 4], 'message: All elements from the first array should be added to the second array in their original order.');",
"assert(testArr1[0] === 1 && testArr1[1] === 2, 'message: The first array should remain the same after the function runs.');",
"assert(testArr2[0] === 'a' && testArr2[1] === 'b', 'message: The second array should remain the same after the function runs.');"
],
"type": "bonfire",
"isRequired": true,
"isBeta": true,
"solutions": [
"function frankenSplice(arr1, arr2, n) {\n // It's alive. It's alive!\n var result = arr2.slice();\n for(var i = 0; i < arr1.length; i++) {\n result.splice(n+i, 0, arr1[i]);\n }\n return result;\n}\n\nfrankenSplice([1, 2, 3], [4, 5], 1);\n"
],
"MDNlinks": [
"Array.prototype.slice()",
"Array.prototype.splice()"
],
"challengeType": 5,
"translations": {
"pt-br": {
"title": "Slice e splice",
"description": [
"Você recebe dois arrays e um índice.",
"Use os métodos de array <code>slice</code> e <code>splice</code> para copiar cada elemento do primeiro array para o segundo array, em ordem.",
"Comece a inserir elementos no índice <code>n</code> do segundo array.",
"Lembre-se de <a href=\"http://forum.freeCodeCamp.com/t/how-to-get-help-when-you-are-stuck/19514\" target=\"_blank\">Ler-Pesquisar-Perguntar</a> se ficar travado. Escreva seu próprio código."
]
}
}
},
{
"id": "adf08ec01beb4f99fc7a68f2",
"title": "Falsy Bouncer",
"description": [
"Remove all falsy values from an array.",
"Falsy values in JavaScript are <code>false</code>, <code>null</code>, <code>0</code>, <code>\"\"</code>, <code>undefined</code>, and <code>NaN</code>.",
"Hint: Try converting each value to a Boolean.",
"Remember to use <a href=\"http://forum.freeCodeCamp.com/t/how-to-get-help-when-you-are-stuck/19514\" target=\"_blank\">Read-Search-Ask</a> if you get stuck. Write your own code."
],
"challengeSeed": [
"function bouncer(arr) {",
" // Don't show a false ID to this bouncer.",
" return arr;",
"}",
"",
"bouncer([7, \"ate\", \"\", false, 9]);"
],
"tests": [
"assert.deepEqual(bouncer([7, \"ate\", \"\", false, 9]), [7, \"ate\", 9], 'message: <code>bouncer([7, \"ate\", \"\", false, 9])</code> should return <code>[7, \"ate\", 9]</code>.');",
"assert.deepEqual(bouncer([\"a\", \"b\", \"c\"]), [\"a\", \"b\", \"c\"], 'message: <code>bouncer([\"a\", \"b\", \"c\"])</code> should return <code>[\"a\", \"b\", \"c\"]</code>.');",
"assert.deepEqual(bouncer([false, null, 0, NaN, undefined, \"\"]), [], 'message: <code>bouncer([false, null, 0, NaN, undefined, \"\"])</code> should return <code>[]</code>.');",
"assert.deepEqual(bouncer([1, null, NaN, 2, undefined]), [1, 2], 'message: <code>bouncer([1, null, NaN, 2, undefined])</code> should return <code>[1, 2]</code>.');"
],
"type": "bonfire",
"isRequired": true,
"solutions": [
"function bouncer(arr) {\n // Don't show a false ID to this bouncer.\n return arr.filter(function(e) {return e;});\n}\n\nbouncer([7, 'ate', '', false, 9]);\n"
],
"MDNlinks": [
"Boolean Objects",
"Array.prototype.filter()"
],
"challengeType": 5,
"translations": {
"es": {
"title": "Detector de Mentiras",
"description": [
"Remueve todos los valores falsy de un arreglo dado",
"En javascript, los valores falsy son los siguientes: <code>false</code>, <code>null</code>, <code>0</code>, <code>\"\"</code>, <code>undefined</code>, y <code>NaN</code>.",
"Recuerda utilizar <a href='http://forum.freeCodeCamp.com/t/how-to-get-help-when-you-are-stuck/19514' target='_blank'>Leer-Buscar-Preguntar</a> si te sientes atascado. Intenta programar en pareja. Escribe tu propio código."
]
},
"pt-br": {
"title": "Detector de mentiras",
"description": [
"Remova todos os valores falsos de um array.",
"Valores falsos em JavaScript são <code>false</code>, <code>null</code>, <code>0</code>, <code>\"\"</code>, <code>undefined</code> e <code>NaN</code>.",
"Dica: Tente converter cada valor para um booleano.",
"Lembre-se de <a href=\"http://forum.freeCodeCamp.com/t/how-to-get-help-when-you-are-stuck/19514\" target=\"_blank\">Ler-Pesquisar-Perguntar</a> se ficar travado. Escreva seu próprio código."
]
}
}
},
{
"id": "a24c1a4622e3c05097f71d67",
"title": "Where do I Belong",
"description": [
"Return the lowest index at which a value (second argument) should be inserted into an array (first argument) once it has been sorted. The returned value should be a number.",
"For example, <code>getIndexToIns([1,2,3,4], 1.5)</code> should return <code>1</code> because it is greater than <code>1</code> (index 0), but less than <code>2</code> (index 1).",
"Likewise, <code>getIndexToIns([20,3,5], 19)</code> should return <code>2</code> because once the array has been sorted it will look like <code>[3,5,20]</code> and <code>19</code> is less than <code>20</code> (index 2) and greater than <code>5</code> (index 1).",
"Remember to use <a href=\"http://forum.freeCodeCamp.com/t/how-to-get-help-when-you-are-stuck/19514\" target=\"_blank\">Read-Search-Ask</a> if you get stuck. Write your own code."
],
"challengeSeed": [
"function getIndexToIns(arr, num) {",
" // Find my place in this sorted array.",
" return num;",
"}",
"",
"getIndexToIns([40, 60], 50);"
],
"tests": [
"assert(getIndexToIns([10, 20, 30, 40, 50], 35) === 3, 'message: <code>getIndexToIns([10, 20, 30, 40, 50], 35)</code> should return <code>3</code>.');",
"assert(typeof(getIndexToIns([10, 20, 30, 40, 50], 35)) === \"number\", 'message: <code>getIndexToIns([10, 20, 30, 40, 50], 35)</code> should return a number.');",
"assert(getIndexToIns([10, 20, 30, 40, 50], 30) === 2, 'message: <code>getIndexToIns([10, 20, 30, 40, 50], 30)</code> should return <code>2</code>.');",
"assert(typeof(getIndexToIns([10, 20, 30, 40, 50], 30)) === \"number\", 'message: <code>getIndexToIns([10, 20, 30, 40, 50], 30)</code> should return a number.');",
"assert(getIndexToIns([40, 60], 50) === 1, 'message: <code>getIndexToIns([40, 60], 50)</code> should return <code>1</code>.');",
"assert(typeof(getIndexToIns([40, 60], 50)) === \"number\", 'message: <code>getIndexToIns([40, 60], 50)</code> should return a number.');",
"assert(getIndexToIns([3, 10, 5], 3) === 0, 'message: <code>getIndexToIns([3, 10, 5], 3)</code> should return <code>0</code>.');",
"assert(typeof(getIndexToIns([3, 10, 5], 3)) === \"number\", 'message: <code>getIndexToIns([3, 10, 5], 3)</code> should return a number.');",
"assert(getIndexToIns([5, 3, 20, 3], 5) === 2, 'message: <code>getIndexToIns([5, 3, 20, 3], 5)</code> should return <code>2</code>.');",
"assert(typeof(getIndexToIns([5, 3, 20, 3], 5)) === \"number\", 'message: <code>getIndexToIns([5, 3, 20, 3], 5)</code> should return a number.');",
"assert(getIndexToIns([2, 20, 10], 19) === 2, 'message: <code>getIndexToIns([2, 20, 10], 19)</code> should return <code>2</code>.');",
"assert(typeof(getIndexToIns([2, 20, 10], 19)) === \"number\", 'message: <code>getIndexToIns([2, 20, 10], 19)</code> should return a number.');",
"assert(getIndexToIns([2, 5, 10], 15) === 3, 'message: <code>getIndexToIns([2, 5, 10], 15)</code> should return <code>3</code>.');",
"assert(typeof(getIndexToIns([2, 5, 10], 15)) === \"number\", 'message: <code>getIndexToIns([2, 5, 10], 15)</code> should return a number.');",
"assert(getIndexToIns([], 1) === 0, 'message: <code>getIndexToIns([], 1)</code> should return <code>0</code>.');",
"assert(typeof(getIndexToIns([], 1)) === \"number\", 'message: <code>getIndexToIns([], 1)</code> should return a number.');"
],
"type": "bonfire",
"isRequired": true,
"solutions": [
"function getIndexToIns(arr, num) {\n arr = arr.sort(function(a, b){return a-b;});\n for (var i = 0; i < arr.length; i++) {\n if (arr[i] >= num)\n {\n return i;\n }\n }\n return arr.length;\n}"
],
"MDNlinks": [
"Array.prototype.sort()"
],
"challengeType": 5,
"translations": {
"es": {
"title": "¿Cuál es mi Asiento?",
"description": [
"Devuelve el menor índice en el que un valor (segundo argumento) debe ser insertado en un arreglo (primer argumento) una vez ha sido ordenado.",
"Por ejemplo, where([1,2,3,4], 1.5) debe devolver 1 porque el segundo argumento de la función (1.5) es mayor que 1 (con índice 0 en el arreglo), pero menor que 2 (con índice 1).",
"Mientras que <code>where([20,3,5], 19)</code> debe devolver <code>2</code> porque una vez ordenado el arreglo se verá com <code>[3,5,20]</code> y <code>19</code> es menor que <code>20</code> (índice 2) y mayor que <code>5</code> (índice 1).",
"Recuerda utilizar <a href='http://forum.freeCodeCamp.com/t/how-to-get-help-when-you-are-stuck/19514' target='_blank'>Leer-Buscar-Preguntar</a> si te sientes atascado. Intenta programar en pareja. Escribe tu propio código."
]
},
"pt-br": {
"title": "Onde é meu lugar?",
"description": [
"Retorne o menor índice no qual um valor (segundo argumento) deve ser inserido num array (primeiro argumento) depois que ele foi ordenado. O valor retornado deve ser um número.",
"Por exemplo, <code>getIndexToIns([1,2,3,4], 1.5)</code> deve retornar <code>1</code> porque <code>1.5</code> é maior que <code>1</code> (índice 0), mas menor que <code>2</code> (índice 1).",
"Da mesma forma, <code>getIndexToIns([20,3,5], 19)</code> deve retornar <code>2</code> porque, depois de ordenado, o array será <code>[3,5,20]</code> e <code>19</code> é menor que <code>20</code> (índice 2) e maior que <code>5</code> (index 1).",
"Lembre-se de <a href=\"http://forum.freeCodeCamp.com/t/how-to-get-help-when-you-are-stuck/19514\" target=\"_blank\">Ler-Pesquisar-Perguntar</a> se ficar travado. Escreva seu próprio código."
]
}
}
},
{
"id": "af2170cad53daa0770fabdea",
"title": "Mutations",
"description": [
"Return true if the string in the first element of the array contains all of the letters of the string in the second element of the array.",
"For example, <code>[\"hello\", \"Hello\"]</code>, should return true because all of the letters in the second string are present in the first, ignoring case.",
"The arguments <code>[\"hello\", \"hey\"]</code> should return false because the string \"hello\" does not contain a \"y\".",
"Lastly, <code>[\"Alien\", \"line\"]</code>, should return true because all of the letters in \"line\" are present in \"Alien\".",
"Remember to use <a href=\"http://forum.freeCodeCamp.com/t/how-to-get-help-when-you-are-stuck/19514\" target=\"_blank\">Read-Search-Ask</a> if you get stuck. Write your own code."
],
"challengeSeed": [
"function mutation(arr) {",
" return arr;",
"}",
"",
"mutation([\"hello\", \"hey\"]);"
],
"tests": [
"assert(mutation([\"hello\", \"hey\"]) === false, 'message: <code>mutation([\"hello\", \"hey\"])</code> should return false.');",
"assert(mutation([\"hello\", \"Hello\"]) === true, 'message: <code>mutation([\"hello\", \"Hello\"])</code> should return true.');",
"assert(mutation([\"zyxwvutsrqponmlkjihgfedcba\", \"qrstu\"]) === true, 'message: <code>mutation([\"zyxwvutsrqponmlkjihgfedcba\", \"qrstu\"])</code> should return true.');",
"assert(mutation([\"Mary\", \"Army\"]) === true, 'message: <code>mutation([\"Mary\", \"Army\"])</code> should return true.');",
"assert(mutation([\"Mary\", \"Aarmy\"]) === true, 'message: <code>mutation([\"Mary\", \"Aarmy\"])</code> should return true.');",
"assert(mutation([\"Alien\", \"line\"]) === true, 'message: <code>mutation([\"Alien\", \"line\"])</code> should return true.');",
"assert(mutation([\"floor\", \"for\"]) === true, 'message: <code>mutation([\"floor\", \"for\"])</code> should return true.');",
"assert(mutation([\"hello\", \"neo\"]) === false, 'message: <code>mutation([\"hello\", \"neo\"])</code> should return false.');",
"assert(mutation([\"voodoo\", \"no\"]) === false, 'message: <code>mutation([\"voodoo\", \"no\"])</code> should return false.');"
],
"type": "bonfire",
"isRequired": true,
"solutions": [
"function mutation(arr) {\n var hash = Object.create(null);\n arr[0].toLowerCase().split('').forEach(function(c) {\n hash[c] = true;\n });\n return !arr[1].toLowerCase().split('').filter(function(c) {\n return !hash[c];\n }).length;\n}\n\nmutation(['hello', 'hey']);\n"
],
"MDNlinks": [
"String.prototype.indexOf()"
],
"challengeType": 5,
"translations": {
"es": {
"title": "Mutaciones",
"description": [
"Crea una función que devuelva <code>true</code> si la cadena de texto del primer elemento de un arreglo contiene todas las letras de la cadena de texto del segundo elemento del arreglo.",
"Por ejemplo, <code>[\"hello\", \"Hello\"]</code>, debe devolver <code>true</code> porque todas las letras en la segunda cadena de texto están presentes en la primera, sin distinguir entre mayúsculas y minúsculas.",
"En el caso de <code>[\"hello\", \"hey\"]</code> la función debe devolver false porque la cadena de texto \"hello\" no contiene una \"y\".",
"Finalmente, <code>[\"Alien\", \"line\"]</code>, la función debe devolver <code>true</code> porque todas las letras en \"line\" están presentes en \"Alien\".",
"Recuerda utilizar <a href='http://forum.freeCodeCamp.com/t/how-to-get-help-when-you-are-stuck/19514' target='_blank'>Leer-Buscar-Preguntar</a> si te sientes atascado. Intenta programar en pareja. Escribe tu propio código."
]
},
"pt-br": {
"title": "Mutações",
"description": [
"Retorne <code>true</code> se a string no primeiro elemento do array contiver todas as letras da string no segundo elemento do array.",
"Por exemplo, para os argumentos <code>[\"hello\", \"Hello\"]</code>, sua função deve retornar <code>true</code>, porque todas as letras da segunda string estão presentes na primeira, ignorando maiúsculas e minúsculas.",
"Para os argumentos <code>[\"hello\", \"hey\"]</code>, sua função deve retornar <code>false</code> porque a string \"hello\" não contém um \"y\".",
"Finalmente, para <code>[\"Alien\", \"line\"]</code>, sua função deve retornar <code>true</code> porque todas as letras em \"line\" estão presentes em \"Alien\".",
"Lembre-se de <a href=\"http://forum.freeCodeCamp.com/t/how-to-get-help-when-you-are-stuck/19514\" target=\"_blank\">Ler-Pesquisar-Perguntar</a> se ficar travado. Escreva seu próprio código."
]
}
}
},
{
"id": "a9bd25c716030ec90084d8a1",
"title": "Chunky Monkey",
"description": [
"Write a function that splits an array (first argument) into groups the length of <code>size</code> (second argument) and returns them as a two-dimensional array.",
"Remember to use <a href=\"http://forum.freeCodeCamp.com/t/how-to-get-help-when-you-are-stuck/19514\" target=\"_blank\">Read-Search-Ask</a> if you get stuck. Write your own code."
],
"challengeSeed": [
"function chunkArrayInGroups(arr, size) {",
" // Break it up.",
" return arr;",
"}",
"",
"chunkArrayInGroups([\"a\", \"b\", \"c\", \"d\"], 2);"
],
"tests": [
"assert.deepEqual(chunkArrayInGroups([\"a\", \"b\", \"c\", \"d\"], 2), [[\"a\", \"b\"], [\"c\", \"d\"]], 'message: <code>chunkArrayInGroups([\"a\", \"b\", \"c\", \"d\"], 2)</code> should return <code>[[\"a\", \"b\"], [\"c\", \"d\"]]</code>.');",
"assert.deepEqual(chunkArrayInGroups([0, 1, 2, 3, 4, 5], 3), [[0, 1, 2], [3, 4, 5]], 'message: <code>chunkArrayInGroups([0, 1, 2, 3, 4, 5], 3)</code> should return <code>[[0, 1, 2], [3, 4, 5]]</code>.');",
"assert.deepEqual(chunkArrayInGroups([0, 1, 2, 3, 4, 5], 2), [[0, 1], [2, 3], [4, 5]], 'message: <code>chunkArrayInGroups([0, 1, 2, 3, 4, 5], 2)</code> should return <code>[[0, 1], [2, 3], [4, 5]]</code>.');",
"assert.deepEqual(chunkArrayInGroups([0, 1, 2, 3, 4, 5], 4), [[0, 1, 2, 3], [4, 5]], 'message: <code>chunkArrayInGroups([0, 1, 2, 3, 4, 5], 4)</code> should return <code>[[0, 1, 2, 3], [4, 5]]</code>.');",
"assert.deepEqual(chunkArrayInGroups([0, 1, 2, 3, 4, 5, 6], 3), [[0, 1, 2], [3, 4, 5], [6]], 'message: <code>chunkArrayInGroups([0, 1, 2, 3, 4, 5, 6], 3)</code> should return <code>[[0, 1, 2], [3, 4, 5], [6]]</code>.');",
"assert.deepEqual(chunkArrayInGroups([0, 1, 2, 3, 4, 5, 6, 7, 8], 4), [[0, 1, 2, 3], [4, 5, 6, 7], [8]], 'message: <code>chunkArrayInGroups([0, 1, 2, 3, 4, 5, 6, 7, 8], 4)</code> should return <code>[[0, 1, 2, 3], [4, 5, 6, 7], [8]]</code>.');",
"assert.deepEqual(chunkArrayInGroups([0, 1, 2, 3, 4, 5, 6, 7, 8], 2), [[0, 1], [2, 3], [4, 5], [6, 7], [8]], 'message: <code>chunkArrayInGroups([0, 1, 2, 3, 4, 5, 6, 7, 8], 2)</code> should return <code>[[0, 1], [2, 3], [4, 5], [6, 7], [8]]</code>.');"
],
"type": "bonfire",
"isRequired": true,
"solutions": [
"function chunkArrayInGroups(arr, size) {\n var out = [];\n for (var i = 0; i < arr.length; i+=size) {\n out.push(arr.slice(i,i+size));\n }\n return out;\n}\n\nchunkArrayInGroups(['a', 'b', 'c', 'd'], 2);\n"
],
"MDNlinks": [
"Array.prototype.push()",
"Array.prototype.slice()"
],
"challengeType": 5,
"translations": {
"es": {
"title": "En mil Pedazos",
"description": [
"Escribe una función que parta un arreglo (primer argumento) en fragmentos de una longitud dada (segundo argumento) y los devuelva en forma de un arreglo bidimensional.",
"Recuerda utilizar <a href='http://forum.freeCodeCamp.com/t/how-to-get-help-when-you-are-stuck/19514' target='_blank'>Leer-Buscar-Preguntar</a> si te sientes atascado. Intenta programar en pareja. Escribe tu propio código."
]
},
"pt-br": {
"title": "Em pedaços",
"description": [
"Escreva uma função que divide um array (primeiro argumento) em grupos de comprimento <code>size</code> (segundo argumento) e retorna esses grupos num array bidimensional.",
"Lembre-se de <a href=\"http://forum.freeCodeCamp.com/t/how-to-get-help-when-you-are-stuck/19514\" target=\"_blank\">Ler-Pesquisar-Perguntar</a> se ficar travado. Escreva seu próprio código."
]
}
}
}
]
}

View File

@@ -0,0 +1,825 @@
{
"name": "Basic Data Structures",
"order": 4,
"time": "1 hour",
"helpRoom": "Help",
"challenges": [
{
"id": "587d7dac367417b2b2516zx5",
"title": "Introduction to Arrays",
"description": [
[
"",
"",
"<dfn>Arrays</dfn> are one of JavaScript's most fundamental built-in data structures, and probably the data structure that you will work with most often throughout the course of the freeCodeCamp curriculum. The array is by no means unique to JavaScript, however &mdash; in fact, its probably safe to say that arrays are utilized by almost every complex program... ever.<br><br>In computer science, an array is a linear collection of elements characterized by the fact that each element has a unique <dfn>index</dfn>, or address, that can be computed and used to look up an element's position at run-time.",
""
],
[
"",
"",
"In Javascript, arrays are written as comma-separated lists and are enclosed in brackets <code>[element1, element2, element3]</code>. They can be any length, and store any type of data supported by JavaScript.<br><br>Arrays can sometimes be simple and serve very basic functionalities, but they can also be complex and very powerful - all of which depends on how the programmer chooses to utilize them<br><br>From this point forward, whenever we refer to the term <dfn>array</dfn>, it will be strictly within the context of JavaScript.",
""
],
[
"",
"",
"JavaScript offers many array <dfn>methods</dfn>, which are a sort of built in function, that allow us to access, traverse, and mutate arrays as needed, depending on our purpose.<br><br>In the coming challenges, we will discuss several of the most common and useful methods, and a few other key techniques, that will help you to better understand and utilize arrays as data structures in JavaScript.",
""
]
],
"releasedOn": "Feb 17, 2017",
"challengeSeed": [],
"tests": [],
"type": "waypoint",
"challengeType": 7,
"isRequired": false,
"translations": {}
},
{
"id": "587d7b7e367417b2b2512b20",
"title": "Use an Array to Store a Collection of Data",
"description": [
"The below is an example of the simplest implementation of an array data structure. This is known as a <dfn>one-dimensional array</dfn>, meaning it only has one level, or that it does not have any other arrays nested within it. Notice it contains <dfn>booleans</dfn>, <dfn>strings</dfn>, and <dfn>numbers</dfn>, among other valid JavaScript data types:",
"<blockquote>let simpleArray = ['one', 2, 'three, true, false, undefined, null];<br>console.log(simpleArray.length);<br>// logs 7</blockquote>",
"All array's have a length property, which as shown above, can be very easily accessed with the syntax <code>Array.length</code>.",
"A more complex implementation of an array can be seen below. This is known as a <dfn>multi-dimensional array</dfn>, or an array that contains other arrays. Notice that this array also contains JavaScript <dfn>objects</dfn>, which we will examine very closely in our next section, but for now, all you need to know is that arrays are also capable of storing complex objects.",
"<blockquote>let complexArray = [<br> [<br> {<br> one: 1,<br> two: 2<br> },<br> {<br> three: 3,<br> four: 4<br> }<br> ],<br> [<br> {<br> a: \"a\",<br> b: \"b\"<br> },<br> {<br> c: \"c\",<br> d: “d”<br> }<br> ]<br>];</blockquote>",
"<hr>",
"We have defined a variable called <code>yourArray</code>. Complete the statement by assigning an array of at least 5 elements in length to the <code>yourArray</code> variable. Your array should contain at least one <dfn>string</dfn>, one <dfn>number</dfn>, and one <dfn>boolean</dfn>."
],
"challengeSeed": [
"let yourArray; // change this line"
],
"tests": [
"assert.strictEqual(Array.isArray(yourArray), true, 'message: yourArray is an array');",
"assert.isAtLeast(yourArray.length, 5, 'message: <code>yourArray</code> is at least 5 elements long');",
"assert(yourArray.filter( el => typeof el === 'boolean').length >= 1, 'message: <code>yourArray</code> contains at least one <code>boolean</code>');",
"assert(yourArray.filter( el => typeof el === 'number').length >= 1, 'message: <code>yourArray</code> contains at least one <code>number</code>');",
"assert(yourArray.filter( el => typeof el === 'string').length >= 1, 'message: <code>yourArray</code> contains at least one <code>string</code>');"
],
"type": "waypoint",
"releasedOn": "Feb 17, 2017",
"solutions": [],
"challengeType": 1,
"translations": {}
},
{
"id": "587d78b2366415b2v2512be3",
"title": "Access an Array's Contents Using Bracket Notation",
"description": [
"The fundamental feature of any data structure is, of course, the ability to not only store data, but to be able to retrieve that data on command. So, now that we've learned how to create an array, let's begin to think about how we can access that array's information.",
"When we define a simple array as seen below, there are 3 items in it:",
"<blockquote>let ourArray = [\"a\", \"b\", \"c\"];</blockquote>",
"In an array, each array item has an <dfn>index</dfn>. This index doubles as the position of that item in the array, and how you reference it. However, it is important to note, that JavaScript arrays are <dfn>zero-indexed</dfn>, meaning that the first element of an array is actually at the <em><strong>zeroth</strong></em> position, not the first.",
"In order to retrieve an element from an array we can enclose an index in brackets and append it to the end of an array, or more commonly, to a variable which references an array object. This is known as <dfn>bracket notation</dfn>.",
"For example, if we want to retrieve the <code>\"a\"</code> from <code>ourArray</code> and assign it to a variable, we can do so with the following code:",
"<blockquote>let ourVariable = ourArray[0];<br>// ourVariable equals \"a\"</blockquote>",
"In addition to accessing the value associated with an index, you can also <em>set</em> an index to a value using the same notation:",
"<blockquote>ourArray[1] = \"not b anymore\";<br>// ourArray now equals [\"a\", \"not b anymore\", \"c\"];</blockquote>",
"Using bracket notation, we have now reset the item at index 1 from <code>\"b\"</code>, to <code>\"not b anymore\"</code>.",
"<hr>",
"In order to complete this challenge, set the 2nd position (index <code>1</code>) of <code>myArray</code> to anything you want, besides <code>\"b\"</code>."
],
"challengeSeed": [
"let myArray = [\"a\", \"b\", \"c\", \"d\"];",
"// change code below this line",
"",
"//change code above this line",
"console.log(myArray);"
],
"tests": [
"assert.strictEqual(myArray[0], \"a\", 'message: <code>myArray[0]</code> is equal to <code>\"a\"</code>');",
"assert.notStrictEqual(myArray[1], \"b\", 'message: <code>myArray[1]</code> is no longer set to <code>\"b\"</code>');",
"assert.strictEqual(myArray[2], \"c\", 'message: <code>myArray[2]</code> is equal to <code>\"c\"</code>');",
"assert.strictEqual(myArray[3], \"d\", 'message: <code>myArray[3]</code> is equal to <code>\"d\"</code>');"
],
"type": "waypoint",
"solutions": [],
"challengeType": 1,
"translations": {}
},
{
"id": "587d78b2367417b2b2512b0e",
"title": "Add Items to an Array with push() and unshift()",
"description": [
"An array's length, like the data types it can contain, is not fixed. Arrays can be defined with a length of any number of elements, and elements can be added or removed over time; in other words, arrays are <dfn>mutable</dfn>. In this challenge, we will look at two methods with which we can programmatically modify an array: <code>Array.push()</code> and <code>Array.unshift()</code>. ",
"Both methods take one or more elements as parameters and add those elements to the array the method is being called on; the <code>push()</code> method adds elements to the end of an array, and <code>unshift()</code> adds elements to the beginning. Consider the following:",
"<blockquote>let twentyThree = 'XXIII';<br>let romanNumerals = ['XXI', 'XXII'];<br><br>romanNumerals.unshift('XIX', 'XX');<br>// now equals ['XIX', 'XX', 'XXI', 'XXII']<br><br>romanNumerals.push(twentyThree);<br>// now equals ['XIX', 'XX', 'XXI', 'XXII', 'XXIII']",
"Notice that we can also pass variables, which allows us even greater flexibility in dynamically modifying our array's data.",
"<hr>",
"We have defined a function, <code>mixedNumbers</code>, which we are passing an array as an argument. Modify the function by using <code>push()</code> and <code>unshift()</code> to add <code>'I', 2, 'three'</code> to the beginning of the array and <code>7, 'VIII', 9</code> to the end so that the returned array contains representations of the numbers 1-9 in order."
],
"challengeSeed": [
"function mixedNumbers(arr) {",
" // change code below this line",
"",
" // change code above this line",
" return arr;",
"}",
"",
"// do not change code below this line",
"console.log(mixedNumbers(['IV', 5, 'six']));"
],
"tests": [
"assert.deepEqual(mixedNumbers(['IV', 5, 'six']), ['I', 2, 'three', 'IV', 5, 'six', 7, 'VIII', 9], 'message: <code>mixedNumbers([\"IV\", 5, \"six\"])</code> should now return <code>[\"I\", 2, \"three\", \"IV\", 5, \"six\", 7, \"VIII\", 9]</code>');",
"assert.notStrictEqual(mixedNumbers.toString().search(/\\.push\\(/), -1, 'message: The <code>mixedNumbers</code> function should utilize the <code>push()</code> method');",
"assert.notStrictEqual(mixedNumbers.toString().search(/\\.unshift\\(/), -1, 'message: The <code>mixedNumbers</code> function should utilize the <code>unshift()</code> method');"
],
"type": "waypoint",
"releasedOn": "Feb 17, 2017",
"solutions": [],
"challengeType": 1,
"translations": {}
},
{
"id": "587d78b2367417b2b2512b0f",
"title": "Remove Items from an Array with pop() and shift()",
"description": [
"Both <code>push()</code> and <code>unshift()</code> have corresponding methods that are nearly functional opposites: <code>pop()</code> and <code>shift()</code>. As you may have guessed by now, instead of adding, <code>pop()</code> <em>removes</em> an element from the end of an array, while <code>shift()</code> removes an element from the beginning. The key difference between <code>pop()</code> and <code>shift()</code> and their cousins <code>push()</code> and <code>unshift()</code>, is that neither method takes parameters, and each only allows an array to be modified by a single element at a time.",
"Let's take a look:",
"<blockquote>let greetings = ['whats up?', 'hello', 'see ya!'];<br><br>greetings.pop();<br>// now equals ['whats up?', 'hello']<br><br>greetings.shift();<br>// now equals ['hello']</blockquote>",
"We can also return the value of the removed element with either method like this:",
"<blockquote>let popped = greetings.pop();<br>// returns 'hello'<br>// greetings now equals []</blockquote>",
"<hr>",
"We have defined a function, <code>popShift</code>, which takes an array as an argument and returns a new array. Modify the function, using <code>pop()</code> and <code>shift()</code>, to remove the first and last elements of the argument array, and assign the removed elements to their corresponding variables, so that the returned array contains their values."
],
"challengeSeed": [
"function popShift(arr) {",
" let popped; // change this line",
" let shifted; // change this line",
" return [shifted, popped];",
"}",
"",
"// do not change code below this line",
"console.log(popShift(['challenge', 'is', 'not', 'complete']));"
],
"tests": [
"assert.deepEqual(popShift(['challenge', 'is', 'not', 'complete']), [\"challenge\", \"complete\"], 'message: <code>popShift([\"challenge\", \"is\", \"not\", \"complete\"])</code> should return <code>[\"challenge\", \"complete\"]</code>');",
"assert.notStrictEqual(popShift.toString().search(/\\.pop\\(/), -1, 'message: The <code>popShift</code> function should utilize the <code>pop()</code> method');",
"assert.notStrictEqual(popShift.toString().search(/\\.shift\\(/), -1, 'message: The <code>popShift</code> function should utilize the <code>shift()</code> method');"
],
"type": "waypoint",
"releasedOn": "Feb 17, 2017",
"solutions": [],
"challengeType": 1,
"translations": {}
},
{
"id": "587d78b2367417b2b2512b10",
"title": "Remove Items Using splice()",
"description": [
"Ok, so we've learned how to remove elements from the beginning and end of arrays using <code>shift()</code> and <code>pop()</code>, but what if we want to remove an element from somewhere in the middle? Or remove more than one element at once? Well, that's where <code>splice()</code> comes in. <code>splice()</code> allows us to do just that: <strong>remove any number of consecutive elements</strong> from anywhere in an array.",
"<code>splice()</code> can take up to 3 parameters, but for now, we'll focus on just the first 2. The first two parameters of <code>splice()</code> are integers which represent indexes, or positions, of the array that <code>splice()</code> is being called upon. And remember, arrays are <em>zero-indexed</em>, so to indicate the first element of an array, we would use <code>0</code>. <code>splice()</code>'s first parameter represents the index on the array from which to begin removing elements, while the second parameter indicates the number of elements to delete. For example:",
"<blockquote>let array = ['today', 'was', 'not', 'so', 'great'];<br><br>array.splice(2, 2);<br>// remove 2 elements beginning with the 3rd element<br>// array now equals ['today', 'was', 'great']</blockquote>",
"<code>splice()</code> not only modifies the array it's being called on, but it also returns a new array containing the value of the removed elements:",
"<blockquote>let array = ['I', 'am', 'feeling', 'really', 'happy'];<br><br>let newArray = array.splice(3, 2);<br>// newArray equals ['really', 'happy']</blockquote>",
"<hr>",
"We've defined a function, <code>sumOfTen</code>, which takes an array as an argument and returns the sum of that array's elements. Modify the function, using <code>splice()</code>, so that it returns a value of <code>10</code>."
],
"challengeSeed": [
"function sumOfTen(arr) {",
" // change code below this line",
" ",
" // change code above this line",
" return arr.reduce((a, b) => a + b);",
"}",
"",
"// do not change code below this line",
"console.log(sumOfTen([2, 5, 1, 5, 2, 1]));"
],
"tests": [
"assert.strictEqual(sumOfTen([2, 5, 1, 5, 2, 1]), 10, 'message: <code>sumOfTen</code> should return 10');",
"assert.notStrictEqual(sumOfTen.toString().search(/\\.splice\\(/), -1, 'message: The <code>sumOfTen</code> function should utilize the <code>splice()</code> method');"
],
"type": "waypoint",
"releasedOn": "Feb 17, 2017",
"solutions": [],
"challengeType": 1,
"translations": {}
},
{
"id": "587d78b3367417b2b2512b11",
"title": "Add Items Using splice()",
"description": [
"Remember in the last challenge we mentioned that <code>splice()</code> can take up to three parameters? Well, we can go one step further with <code>splice()</code> &mdash; in addition to removing elements, we can use that third parameter, which represents one or more elements, to <em>add</em> them as well. This can be incredibly useful for quickly switching out an element, or a set of elements, for another. For instance, let's say you're storing a color scheme for a set of DOM elements in an array, and want to dynamically change a color based on some action:",
"<blockquote>function colorChange(arr, index, newColor) {<br>&nbsp;&nbsp;arr.splice(index, 1, newColor);<br>&nbsp;&nbsp;return arr;<br>}<br><br>let colorScheme = ['#878787', '#a08794', '#bb7e8c', '#c9b6be', '#d1becf'];<br><br>colorScheme = colorChange(colorScheme, 2, '#332327');<br>// we have removed '#bb7e8c' and added '#332327' in its place<br>// colorScheme now equals ['#878787', '#a08794', '#332327', '#c9b6be', '#d1becf']</blockquote>",
"This function takes an array of hex values, an index at which to remove an element, and the new color to replace the removed element with. The return value is an array containing a newly modified color scheme! While this example is a bit oversimplified, we can see the value that utilizing <code>splice()</code> to its maximum potential can have.",
"<hr>",
"We have defined a function, <code>htmlColorNames</code>, which takes an array of HTML colors as an argument. Modify the function using <code>splice()</code> to remove the first two elements of the array and add <code>'DarkSalmon'</code> and <code>'BlanchedAlmond'</code> in their respective places."
],
"challengeSeed": [
"function htmlColorNames(arr) {",
" // change code below this line",
" ",
" // change code above this line",
" return arr;",
"} ",
" ",
"// do not change code below this line",
"console.log(htmlColorNames(['DarkGoldenRod', 'WhiteSmoke', 'LavenderBlush', 'PaleTurqoise', 'FireBrick']));"
],
"tests": [
"assert.deepEqual(htmlColorNames(['DarkGoldenRod', 'WhiteSmoke', 'LavenderBlush', 'PaleTurqoise', 'FireBrick']), ['DarkSalmon', 'BlanchedAlmond', 'LavenderBlush', 'PaleTurqoise', 'FireBrick'], 'message: <code>htmlColorNames</code> should return <code>[\"DarkSalmon\", \"BlanchedAlmond\", \"LavenderBlush\", \"PaleTurqoise\", \"FireBrick\"]</code>');",
"assert(/.splice/.test(code), 'message: The <code>htmlColorNames</code> function should utilize the <code>splice()</code> method');",
"assert(!/shift|unshift/.test(code), 'message: You should not use <code>shift()</code> or <code>unshift()</code>.');",
"assert(!/\\[\\d\\]\\s*=/.test(code), 'message: You should not use array bracket notation.');"
],
"type": "waypoint",
"releasedOn": "Feb 17, 2017",
"solutions": [],
"challengeType": 1,
"translations": {}
},
{
"id": "587d7b7a367417b2b2512b12",
"title": "Copy Array Items Using slice()",
"description": [
"The next method we will cover is <code>slice()</code>. <code>slice()</code>, rather than modifying an array, copies, or <em>extracts</em>, a given number of elements to a new array, leaving the array it is called upon untouched. <code>slice()</code> takes only 2 parameters &mdash; the first is the index at which to begin extraction, and the second is the index at which to stop extraction (extraction will occur up to, but not including the element at this index). Consider this:",
"<blockquote>let weatherConditions = ['rain', 'snow', 'sleet', 'hail', 'clear'];<br><br>let todaysWeather = weatherConditions.slice(1, 3);<br>// todaysWeather equals ['snow', 'sleet'];<br>// weatherConditions still equals ['rain', 'snow', 'sleet', 'hail', 'clear']<br></blockquote>",
"In effect, we have created a new array by extracting elements from an existing array.",
"<hr>",
"We have defined a function, <code>forecast</code>, that takes an array as an argument. Modify the function using <code>slice()</code> to extract information from the argument array and return a new array that contains the elements <code>'warm'</code> and <code>'sunny'</code>."
],
"challengeSeed": [
"function forecast(arr) {",
" // change code below this line",
" ",
" return arr;",
"}",
"",
"// do not change code below this line",
"console.log(forecast(['cold', 'rainy', 'warm', 'sunny', 'cool', 'thunderstorms']));"
],
"tests": [
"assert.deepEqual(forecast(['cold', 'rainy', 'warm', 'sunny', 'cool', 'thunderstorms']), ['warm', 'sunny'], 'message: <code>forecast</code> should return <code>[\"warm\", \"sunny\"]');",
"assert(/\\.slice\\(/.test(code), 'message: The <code>forecast</code> function should utilize the <code>slice()</code> method');"
],
"type": "waypoint",
"releasedOn": "Feb 17, 2017",
"solutions": [],
"challengeType": 1,
"translations": {}
},
{
"id": "587d7b7b367417b2b2512b13",
"title": "Copy an Array with the Spread Operator",
"description": [
"While <code>slice()</code> allows us to be selective about what elements of an array to copy, among several other useful tasks, ES6's new <dfn>spread operator</dfn> allows us to easily copy <em>all</em> of an array's elements, in order, with a simple and highly readable syntax. The spread syntax simply looks like this: <code>...</code>",
"In practice, we can use the spread operator to copy an array like so:",
"<blockquote>let thisArray = [true, true, undefined, false, null];<br>let thatArray = [...thisArray];<br>// thatArray equals [true, true, undefined, false, null]<br>// thisArray remains unchanged, and is identical to thatArray</blockquote>",
"<hr>",
"We have defined a function, <code>copyMachine</code> which takes <code>arr</code> (an array) and <code>num</code> (a number) as arguments. The function is supposed to return a new array made up of <code>num</code> copies of <code>arr</code>. We have done most of the work for you, but it doesn't work quite right yet. Modify the function using spread syntax so that it works correctly (hint: another method we have already covered might come in handy here!)."
],
"challengeSeed": [
"function copyMachine(arr, num) {",
" let newArr = [];",
" while (num >= 1) {",
" // change code below this line",
"",
" // change code above this line",
" num--;",
" }",
" return newArr;",
"}",
"",
"// change code here to test different cases:",
"console.log(copyMachine([true, false, true], 2));"
],
"tests": [
"assert.deepEqual(copyMachine([true, false, true], 2), [[true, false, true], [true, false, true]], 'message: <code>copyMachine([true, false, true], 2)</code> should return <code>[[true, false, true], [true, false, true]]</code>');",
"assert.deepEqual(copyMachine([1, 2, 3], 5), [[1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3]], 'message: <code>copyMachine([1, 2, 3], 5)</code> should return <code>[[1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3]]</code>');",
"assert.deepEqual(copyMachine([true, true, null], 1), [[true, true, null]], 'message: <code>copyMachine([true, true, null], 1)</code> should return <code>[[true, true, null]]</code>');",
"assert.deepEqual(copyMachine(['it works'], 3), [['it works'], ['it works'], ['it works']], 'message: <code>copyMachine([\"it works\"], 3)</code> should return <code>[[\"it works\"], [\"it works\"], [\"it works\"]]</code>');",
"assert.notStrictEqual(copyMachine.toString().indexOf('.concat(_toConsumableArray(arr))'), -1, 'message: The <code>copyMachine</code> function should utilize the <code>spread operator</code> with array <code>arr</code>');"
],
"type": "waypoint",
"releasedOn": "Feb 17, 2017",
"solutions": [],
"challengeType": 1,
"translations": {}
},
{
"id": "587d7b7b367417b2b2512b17",
"title": "Combine Arrays with the Spread Operator",
"description": [
"Another huge advantage of the <dfn>spread</dfn> operator, is the ability to combine arrays, or to insert all the elements of one array into another, at any index. With more traditional syntaxes, we can concatenate arrays, but this only allows us to combine arrays at the end of one, and at the start of another. Spread syntax makes the following operation extremely simple:",
"<blockquote>let thisArray = ['sage', 'rosemary', 'parsley', 'thyme'];<br><br>let thatArray = ['basil', 'cilantro', ...thisArray, 'coriander'];<br>// thatArray now equals ['basil', 'cilantro', 'sage', 'rosemary', 'parsley', 'thyme', 'coriander']</blockquote>",
"Using spread syntax, we have just achieved an operation that would have been more more complex and more verbose had we used traditional methods.",
"<hr>",
"We have defined a function <code>spreadOut</code> that returns the variable <code>sentence</code>, modify the function using the <dfn>spread</dfn> operator so that it returns the array <code>['learning', 'to', 'code', 'is', 'fun']</code>."
],
"challengeSeed": [
"function spreadOut() {",
" let fragment = ['to', 'code'];",
" let sentence; // change this line",
" return sentence;",
"}",
"",
"// do not change code below this line",
"console.log(spreadOut());"
],
"tests": [
"assert.deepEqual(spreadOut(), ['learning', 'to', 'code', 'is', 'fun'], 'message: <code>spreadOut</code> should return <code>[\"learning\", \"to\", \"code\", \"is\", \"fun\"]</code>');",
"assert.notStrictEqual(spreadOut.toString().search(/[...]/), -1, 'message: The <code>spreadOut</code> function should utilize spread syntax');"
],
"type": "waypoint",
"releasedOn": "Feb 17, 2017",
"solutions": [],
"challengeType": 1,
"translations": {}
},
{
"id": "587d7b7b367417b2b2512b14",
"title": "Check For The Presence of an Element With indexOf()",
"description": [
"Since arrays can be changed, or <em>mutated</em>, at any time, there's no guarantee about where a particular piece of data will be on a given array, or if that element even still exists. Luckily, JavaScript provides us with another built-in method, <code>indexOf()</code>, that allows us to quickly and easily check for the presence of an element on an array. <code>indexOf()</code> takes an element as a parameter, and when called, it returns the position, or index, of that element, or <code>-1</code> if the element does not exist on the array.",
"For example:",
"<blockquote>let fruits = ['apples', 'pears', 'oranges', 'peaches', 'pears'];<br><br>fruits.indexOf('dates') // returns -1<br>fruits.indexOf('oranges') // returns 2<br>fruits.indexOf('pears') // returns 1, the first index at which the element exists</blockquote>",
"<hr>",
"<code>indexOf()</code> can be incredibly useful for quickly checking for the presence of an element on an array. We have defined a function, <code>quickCheck</code>, that takes an array and an element as arguments. Modify the function using <code>indexOf()</code> so that it returns <code>true</code> if the passed element exists on the array, and <code>false</code> if it does not."
],
"challengeSeed": [
"function quickCheck(arr, elem) {",
" // change code below this line",
"",
" // change code above this line",
"}",
"",
"// change code here to test different cases:",
"console.log(quickCheck(['squash', 'onions', 'shallots'], 'mushrooms'));"
],
"tests": [
"assert.strictEqual(quickCheck(['squash', 'onions', 'shallots'], 'mushrooms'), false, 'message: <code>quickCheck([\"squash\", \"onions\", \"shallots\"], \"mushrooms\")</code> should return <code>false</code>');",
"assert.strictEqual(quickCheck(['squash', 'onions', 'shallots'], 'onions'), true, 'message: <code>quickCheck([\"squash\", \"onions\", \"shallots\"], \"onions\")</code> should return <code>true</code>');",
"assert.strictEqual(quickCheck([3, 5, 9, 125, 45, 2], 125), true, 'message: <code>quickCheck([3, 5, 9, 125, 45, 2], 125)</code> should return <code>true</code>');",
"assert.strictEqual(quickCheck([true, false, false], undefined), false, 'message: <code>quickCheck([true, false, false], undefined)</code> should return <code>false</code>');",
"assert.notStrictEqual(quickCheck.toString().search(/\\.indexOf\\(/), -1, 'message: The <code>quickCheck</code> function should utilize the <code>indexOf()</code> method');"
],
"type": "waypoint",
"releasedOn": "Feb 17, 2017",
"solutions": [],
"challengeType": 1,
"translations": {}
},
{
"id": "587d7b7b367417b2b2512b15",
"title": "Iterate Through All an Array's Items Using For Loops",
"description": [
"Sometimes when working with arrays, it is very handy to be able to iterate through each item to find one or more elements that we might need, or to manipulate an array based on which data items meet a certain set of criteria. JavaScript offers several built in methods that each iterate over arrays in slightly different ways to achieve different results (such as <code>every()</code>, <code>forEach()</code>, <code>map()</code>, etc.), however the technique which is most flexible and offers us the greatest amount of control is a simple <code>for</code> loop.",
"Consider the following:",
"<blockquote>function greaterThanTen(arr) {<br>&nbsp;&nbsp;let newArr = [];<br>&nbsp;&nbsp;for (let i = 0; i < arr.length; i++) {<br>&nbsp;&nbsp;&nbsp;&nbsp;if (arr[i] > 10) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;newArr.push(arr[i]);<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;}<br>&nbsp;&nbsp;return newArr;<br>}<br><br>greaterThanTen([2, 12, 8, 14, 80, 0, 1]);<br>// returns [12, 14, 80]</blockquote>",
"Using a <code>for</code> loop, this function iterates through and accesses each element of the array, and subjects it to a simple test that we have created. In this way, we have easily and programmatically determined which data items are greater than <code>10</code>, and returned a new array containing those items.",
"<hr>",
"We have defined a function, <code>filteredArray</code>, which takes <code>arr</code>, a nested array, and <code>elem</code> as arguments, and returns a new array. <code>elem</code> represents an element that may or may not be present on one or more of the arrays nested within <code>arr</code>. Modify the function, using a <code>for</code> loop, to return a filtered version of the passed array such that any array nested within <code>arr</code> containing <code>elem</code> has been removed."
],
"challengeSeed": [
"function filteredArray(arr, elem) {",
" let newArr = [];",
" // change code below this line",
"",
" // change code above this line",
" return newArr;",
"}",
"",
"// change code here to test different cases:",
"console.log(filteredArray([[3, 2, 3], [1, 6, 3], [3, 13, 26], [19, 3, 9]], 3));"
],
"tests": [
"assert.deepEqual(filteredArray([ [10, 8, 3], [14, 6, 23], [3, 18, 6] ], 18), [[10, 8, 3], [14, 6, 23]], 'message: <code>filteredArray([[10, 8, 3], [14, 6, 23], [3, 18, 6]], 18)</code> should return <code>[ [10, 8, 3], [14, 6, 23] ]</code>');",
"assert.deepEqual(filteredArray([ ['trumpets', 2], ['flutes', 4], ['saxophones', 2] ], 2), [['flutes', 4]], 'message: <code>filteredArray([ [\"trumpets\", 2], [\"flutes\", 4], [\"saxophones\", 2] ], 2)</code> should return <code>[ [\"flutes\", 4] ]</code>');",
"assert.deepEqual(filteredArray([['amy', 'beth', 'sam'], ['dave', 'sean', 'peter']], 'peter'), [['amy', 'beth', 'sam']], 'message: <code>filteredArray([ [\"amy\", \"beth\", \"sam\"], [\"dave\", \"sean\", \"peter\"] ], \"peter\")</code> should return <code>[ [\"amy\", \"beth\", \"sam\"] ]</code>');",
"assert.deepEqual(filteredArray([[3, 2, 3], [1, 6, 3], [3, 13, 26], [19, 3, 9]], 3), [], 'message: <code>filteredArray([[3, 2, 3], [1, 6, 3], [3, 13, 26], [19, 3, 9]], 3)</code> should return <code>[ ]</code>');",
"assert.notStrictEqual(filteredArray.toString().search(/for/), -1, 'message: The <code>filteredArray</code> function should utilize a <code>for</code> loop');"
],
"type": "waypoint",
"releasedOn": "Feb 17, 2017",
"solutions": [],
"challengeType": 1,
"translations": {}
},
{
"id": "587d7b7b367417b2b2512b16",
"title": "Create complex multi-dimensional arrays",
"description": [
"Awesome! You have just learned a ton about arrays! This has been a fairly high level overview, and there is plenty more to learn about working with arrays, much of which you will see in later sections. But before moving on to looking at <dfn>Objects</dfn>, lets take one more look, and see how arrays can become a bit more complex than what we have seen in previous challenges.",
"One of the most powerful features when thinking of arrays as data structures, is that arrays can contain, or even be completely made up of other arrays. We have seen arrays that contain arrays in previous challenges, but fairly simple ones. However, arrays can contain an infinite depth of arrays that can contain other arrays, each with their own arbitrary levels of depth, and so on. In this way, an array can very quickly become very complex data structure, known as a <dfn>multi-dimensional</dfn>, or nested array. Consider the following example:",
"<blockquote>let nestedArray = [ // top, or first level - the outer most array<br>&nbsp;&nbsp;['deep'], // an array within an array, 2 levels of depth<br>&nbsp;&nbsp;[<br>&nbsp;&nbsp;&nbsp;&nbsp;['deeper'], ['deeper'] // 2 arrays nested 3 levels deep<br>&nbsp;&nbsp;],<br>&nbsp;&nbsp;[<br>&nbsp;&nbsp;&nbsp;&nbsp;[<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;['deepest'], ['deepest'] // 2 arrays nested 4 levels deep<br>&nbsp;&nbsp;&nbsp;&nbsp;],<br>&nbsp;&nbsp;&nbsp;&nbsp;[<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;['deepest-est?'] // an array nested 5 levels deep<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;]<br>&nbsp;&nbsp;&nbsp;&nbsp;]<br>&nbsp;&nbsp;]<br>];</blockquote>",
"While this example may seem convoluted, this level of complexity is not unheard of, or even unusual, when dealing with large amounts of data.",
"However, we can still very easily access the deepest levels of an array this complex with bracket notation:",
"<blockquote>console.log(nestedArray[2][1][0][0][0]);<br>// logs: deepest-est?</blockquote>",
"And now that we know where that piece of data is, we can reset it if we need to:",
"<blockquote>nestedArray[2][1][0][0][0] = 'deeper still';<br><br>console.log(nestedArray[2][1][0][0][0]);<br>// now logs: deeper still</blockquote>",
"<hr>",
"We have defined a variable, <code>myNestedArray</code>, set equal to an array. Modify <code>myNestedArray</code>, using any combination of <dfn>strings</dfn>, <dfn>numbers</dfn>, and <dfn>booleans</dfn> for data elements, so that it has exactly five levels of depth (remember, the outer-most array is level 1). Somewhere on the third level, include the string <code>'deep'</code>, on the fourth level, include the string <code>'deeper'</code>, and on the fifth level, include the string <code>'deepest'</code>."
],
"challengeSeed": [
"let myNestedArray = [",
" // change code below this line",
" ['unshift', false, 1, 2, 3, 'complex', 'nested'],",
" ['loop', 'shift', 6, 7, 1000, 'method'],",
" ['concat', false, true, 'spread', 'array'],",
" ['mutate', 1327.98, 'splice', 'slice', 'push'],",
" ['iterate', 1.3849, 7, '8.4876', 'arbitrary', 'depth']",
" // change code above this line",
"];"
],
"tests": [
"assert.strictEqual((function(arr) { let flattened = (function flatten(arr) { const flat = [].concat(...arr); return flat.some (Array.isArray) ? flatten(flat) : flat; })(arr); for (let i = 0; i < flattened.length; i++) { if ( typeof flattened[i] !== 'number' && typeof flattened[i] !== 'string' && typeof flattened[i] !== 'boolean') { return false } } return true })(myNestedArray), true, 'message: <code>myNestedArray</code> should contain only numbers, booleans, and strings as data elements');",
"assert.strictEqual((function(arr) {let depth = 0;function arrayDepth(array, i, d) { if (Array.isArray(array[i])) { arrayDepth(array[i], 0, d + 1);} else { depth = (d > depth) ? d : depth;}if (i < array.length) { arrayDepth(array, i + 1, d);} }arrayDepth(arr, 0, 0);return depth;})(myNestedArray), 4, 'message: <code>myNestedArray</code> should have exactly 5 levels of depth');",
"assert((function howDeep(array, target, depth = 0) {return array.reduce((combined, current) => {if (Array.isArray(current)) { return combined.concat(howDeep(current, target, depth + 1));} else if (current === target) { return combined.concat(depth);} else { return combined;}}, []);})(myNestedArray, 'deep').length === 1 && (function howDeep(array, target, depth = 0) {return array.reduce((combined, current) => {if (Array.isArray(current)) { return combined.concat(howDeep(current, target, depth + 1));} else if (current === target) { return combined.concat(depth);} else { return combined;}}, []);})(myNestedArray, 'deep')[0] === 2, 'message: <code>myNestedArray</code> should contain exactly one occurrence of the string <code>\"deep\"</code> on an array nested 3 levels deep');",
"assert((function howDeep(array, target, depth = 0) {return array.reduce((combined, current) => {if (Array.isArray(current)) { return combined.concat(howDeep(current, target, depth + 1));} else if (current === target) { return combined.concat(depth);} else { return combined;}}, []);})(myNestedArray, 'deeper').length === 1 && (function howDeep(array, target, depth = 0) {return array.reduce((combined, current) => {if (Array.isArray(current)) { return combined.concat(howDeep(current, target, depth + 1));} else if (current === target) { return combined.concat(depth);} else { return combined;}}, []);})(myNestedArray, 'deeper')[0] === 3, 'message: <code>myNestedArray</code> should contain exactly one occurrence of the string <code>\"deeper\"</code> on an array nested 4 levels deep');",
"assert((function howDeep(array, target, depth = 0) {return array.reduce((combined, current) => {if (Array.isArray(current)) { return combined.concat(howDeep(current, target, depth + 1));} else if (current === target) { return combined.concat(depth);} else { return combined;}}, []);})(myNestedArray, 'deepest').length === 1 && (function howDeep(array, target, depth = 0) {return array.reduce((combined, current) => {if (Array.isArray(current)) { return combined.concat(howDeep(current, target, depth + 1));} else if (current === target) { return combined.concat(depth);} else { return combined;}}, []);})(myNestedArray, 'deepest')[0] === 4, 'message: <code>myNestedArray</code> should contain exactly one occurrence of the string <code>\"deepest\"</code> on an array nested 5 levels deep');"
],
"type": "waypoint",
"releasedOn": "Feb 17, 2017",
"solutions": [],
"challengeType": 1,
"translations": {}
},
{
"id": "587d7dac367417b2b25184d3",
"title": "Introduction to Objects",
"description": [
[
"",
"",
"The next data structure we will discuss is the JavaScript <dfn>object</dfn>. Like arrays, objects are a fundamental part of JavaScript. However, it is probably safe to say that objects surpass arrays in flexibility, usefulness and in their overall importance to the language &mdash; in fact, you may have heard this line before: 'In JavaScript, everything is an object.'<br><br>While an understanding of objects is important to understand the inner workings of JavaScript functions or JavaScript's object-oriented capabilities, JavaScript objects at a basic level are actually just <dfn>key-value pair</dfn> stores, a commonly used data structure across almost all programming languages. Here, we will confine our discussion to JavaScript objects in this capacity.",
""
],
[
"",
"",
"Key-value pair data structures go by different names depending on the language and the specific details of the data structure. The terms <dfn>dictionary</dfn>, <dfn>map</dfn>, and <dfn>hash table</dfn> all refer to the notion of a data structure in which specific keys, or properties, are mapped to specific values.<br><br>Objects, and other similar key-value pair data structures, offer some very useful benefits. One clear benefit is that they allow us to structure our data in an intuitive way; properties can be nested to an arbitrary depth, and values can be anything, including arrays and even other objects.<br><br>Largely due to this flexibility, objects are also the foundation for <dfn>JavaScript Object Notation</dfn>, or <dfn>JSON</dfn>, which is a widely used method of sending data across the web.",
""
],
[
"",
"",
"Another powerful advantage of key-value pair data structures is <dfn>constant lookup time</dfn>. What this means, is that when you request the value of a specific property, you will get the value back in the same amount of time (theoretically) regardless of the number of entries in the object. If you had an object with 5 entries or one that held a collection of 1,000,000, you could still retrieve property values or check if a key exists in the same amount of time.<br><br>The reason for this fast lookup time, is that internally, the object is storing properties using a hashing mechanism which allows it to know exactly where it has stored different property values. If you want to learn more about this please take a look at the optional Advanced Data Structures challenges. All you should remember for now is that <strong>performant access to flexibly structured data make key-value stores very attractive data structures useful in a wide variety of settings</strong>.",
""
],
[
"",
"",
"<br><br>In JavaScript, objects are written as comma-separated lists of key-value pairs, wrapped in curly brackets, with each key and its assigned value separated by a colon:<br> <code>{ key1: 'val-1', key2: 'val-2' }</code><br><br>In the next few challenges, we will examine JavaScript objects more closely, and take a look at <dfn>methods</dfn> and techniques that allow us to access, store, and manipulate an object's data.<br><br>Note that throughout the scope of this discussion, and in general when considering JavaScript objects, the terms <dfn>key</dfn> and <dfn>property</dfn> will be used interchangeably.",
""
]
],
"releasedOn": "Feb 17, 2017",
"challengeSeed": [],
"tests": [],
"type": "waypoint",
"challengeType": 7,
"isRequired": false,
"translations": {}
},
{
"id": "587d7b7c367417b2b2512b18",
"title": "Add Key-Value Pairs to JavaScript Objects",
"description": [
"At their most basic, objects are just collections of <dfn>key-value pairs</dfn>, or in other words, pieces of data mapped to unique identifiers that we call <dfn>properties</dfn> or <dfn>keys</dfn>. Let's take a look at a very simple example:",
"<blockquote>let FCC_User = {<br> username: 'awesome_coder',<br> followers: 572,<br> points: 1741,<br> completedProjects: 15<br>};</blockquote>",
"The above code defines an object called <code>FCC_User</code> that has four <dfn>properties</dfn>, each of which map to a specific value. If we wanted to know the number of <code>followers</code> <code>FCC_User</code> has, we can access that property by writing:",
"<blockquote>let userData = FCC_User.followers;<br>// userData equals 572</blockquote>",
"This is called <dfn>dot notation</dfn>. Alternatively, we can also access the property with brackets, like so:",
"<blockquote>let userData = FCC_User['followers']<br>// userData equals 572</blockquote>",
"Notice that with <dfn>bracket notation</dfn>, we enclosed <code>followers</code> in quotes. This is because the brackets actually allow us to pass a variable in to be evaluated as a property name (hint: keep this in mind for later!). Had we passed <code>followers</code> in without the quotes, the JavaScript engine would have attempted to evaluate it as a variable, and a <code>ReferenceError: followers is not defined</code> would have been thrown.",
"<hr>",
"Using the same syntax, we can also <em><strong>add new</strong></em> key-value pairs to objects. We've created a <code>foods</code> object with three entries. Add three more entries: <code>bananas</code> with a value of <code>13</code>, <code>grapes</code> with a value of <code>35</code>, and <code>strawberries</code> with a value of <code>27</code>."
],
"challengeSeed": [
"let foods = {",
" apples: 25,",
" oranges: 32,",
" plums: 28",
"};",
"",
"// change code below this line",
"",
"// change code above this line",
"",
"console.log(foods);"
],
"tests": [
"assert(typeof foods === 'object', 'message: <code>foods</code> is an object');",
"assert(foods.bananas === 13, 'message: The <code>foods</code> object has a key <code>\"bananas\"</code> with a value of <code>13</code>');",
"assert(foods.grapes === 35, 'message: The <code>foods</code> object has a key <code>\"grapes\"</code> with a value of <code>35</code>');",
"assert(foods.strawberries === 27, 'message: The <code>foods</code> object has a key <code>\"strawberries\"</code> with a value of <code>27</code>');",
"assert(code.search(/bananas:/) === -1 && code.search(/grapes:/) === -1 && code.search(/strawberries:/) === -1, 'message: The key-value pairs should be set using dot or bracket notation');"
],
"type": "waypoint",
"releasedOn": "Feb 17, 2017",
"solutions": [],
"challengeType": 1,
"translations": {}
},
{
"id": "587d7b7c367417b2b2512b19",
"title": "Modify an Object Nested Within an Object",
"description": [
"Now let's take a look at a slightly more complex object. Object properties can be nested to an arbitrary depth, and their values can be any type of data supported by JavaScript, including arrays and even other objects. Consider the following:",
"<blockquote>let nestedObject = {<br> id: 28802695164,<br> date: 'December 31, 2016',<br> data: {<br> totalUsers: 99,<br> online: 80,<br> onlineStatus: {<br> active: 67,<br> away: 13<br> }<br> }<br>};</blockquote>",
"<code>nestedObject</code> has three unique keys: <code>id</code>, whose value is a number, <code>date</code> whose value is a string, and <code>data</code>, whose value is an object which has yet another object nested within it. While structures can quickly become complex, we can still use the same notations to access the information we need.",
"<hr>",
"Here we've defined an object, <code>userActivity</code>, which includes another object nested within it. You can modify properties on this nested object in the same way you modified properties in the last challenge. Set the value of the <code>online</code> key to <code>45</code>."
],
"challengeSeed": [
"let userActivity = {",
" id: 23894201352,",
" date: 'January 1, 2017',",
" data: {",
" totalUsers: 51,",
" online: 42",
" }",
"};",
"",
"// change code below this line",
"",
"// change code above this line",
"",
"console.log(userActivity);"
],
"tests": [
"assert('id' in userActivity && 'date' in userActivity && 'data' in userActivity, 'message: <code>userActivity</code> has <code>id</code>, <code>date</code> and <code>data</code> properties');",
"assert('totalUsers' in userActivity.data && 'online' in userActivity.data, 'message: <code>userActivity</code> has a <code>data</code> key set to an object with keys <code>totalUsers</code> and <code>online</code>');",
"assert(userActivity.data.online === 45, 'message: The <code>online</code> property nested in the <code>data</code> key of <code>userActivity</code> should be set to <code>45</code>');",
"assert.strictEqual(code.search(/online: 45/), -1, 'message: The <code>online</code> property is set using dot or bracket notation');"
],
"type": "waypoint",
"releasedOn": "Feb 17, 2017",
"solutions": [],
"challengeType": 1,
"translations": {}
},
{
"id": "587d7b7c367417b2b2512b1a",
"title": "Access Property Names with Bracket Notation",
"description": [
"In the first object challenge we mentioned the use of bracket notation as a way to access property values using the evaluation of a variable. For instance, imagine that our <code>foods</code> object is being used in a program for a supermarket cash register. We have some function that sets the <code>selectedFood</code> and we want to check our <code>foods</code> object for the presence of that food. This might look like:",
"<blockquote>let selectedFood = getCurrentFood(scannedItem);<br>let inventory = foods[selectedFood];</blockquote>",
"This code will evaluate the value stored in the <code>selectedFood</code> variable and return the value of that key in the <code>foods</code> object, or <code>undefined</code> if it is not present. Bracket notation is very useful because sometimes object properties are not known before runtime or we need to access them in a more dynamic way.",
"<hr>",
"We've defined a function, <code>checkInventory</code>, which receives a scanned item as an argument. Return the current value of the <code>scannedItem</code> key in the <code>foods</code> object. You can assume that only valid keys will be provided as an argument to <code>checkInventory</code>."
],
"challengeSeed": [
"let foods = {",
" apples: 25,",
" oranges: 32,",
" plums: 28,",
" bananas: 13,",
" grapes: 35,",
" strawberries: 27",
"};",
"// do not change code above this line",
"",
"function checkInventory(scannedItem) {",
" // change code below this line",
"",
"}",
"",
"// change code below this line to test different cases:",
"console.log(checkInventory(\"apples\"));"
],
"tests": [
"assert.strictEqual(typeof checkInventory, 'function', 'message: <code>checkInventory</code> is a function');",
"assert.deepEqual(foods, {apples: 25, oranges: 32, plums: 28, bananas: 13, grapes: 35, strawberries: 27}, 'message: The <code>foods</code> object should have only the following key-value pairs: <code>apples: 25</code>, <code>oranges: 32</code>, <code>plums: 28</code>, <code>bananas: 13</code>, <code>grapes: 35</code>, <code>strawberries: 27</code>');",
"assert.strictEqual(checkInventory('apples'), 25, 'message: <code>checkInventory(\"apples\")</code> should return <code>25</code>');",
"assert.strictEqual(checkInventory('bananas'), 13, 'message: <code>checkInventory(\"bananas\")</code> should return <code>13</code>');",
"assert.strictEqual(checkInventory('strawberries'), 27, 'message: <code>checkInventory(\"strawberries\")</code> should return <code>27</code>');"
],
"type": "waypoint",
"releasedOn": "Feb 17, 2017",
"solutions": [],
"challengeType": 1,
"translations": {}
},
{
"id": "587d7b7c367417b2b2512b1b",
"title": "Use the delete Keyword to Remove Object Properties",
"description": [
"Now you know what objects are and their basic features and advantages. In short, they are key-value stores which provide a flexible, intuitive way to structure data, <strong><em>and</em></strong>, they provide very fast lookup time. Throughout the rest of these challenges, we will describe several common operations you can perform on objects so you can become comfortable applying these useful data structures in your programs.",
"In earlier challenges, we have both added to and modified an object's key-value pairs. Here we will see how we can <em>remove</em> a key-value pair from an object.",
"Let's revisit our <code>foods</code> object example one last time. If we wanted to remove the <code>apples</code> key, we can remove it by using the <code>delete</code> keyword like this:",
"<blockquote>delete foods.apples;</blockquote>",
"<hr>",
"Use the delete keyword to remove the <code>oranges</code>, <code>plums</code>, and <code>strawberries</code> keys from the <code>foods</code> object."
],
"challengeSeed": [
"let foods = {",
" apples: 25,",
" oranges: 32,",
" plums: 28,",
" bananas: 13,",
" grapes: 35,",
" strawberries: 27",
"};",
"",
"// change code below this line",
"",
"// change code above this line",
"",
"console.log(foods);"
],
"tests": [
"assert(!foods.hasOwnProperty('oranges') && !foods.hasOwnProperty('plums') && !foods.hasOwnProperty('strawberries') && Object.keys(foods).length === 3, 'message: The <code>foods</code> object only has three keys: <code>apples</code>, <code>grapes</code>, and <code>bananas</code>');",
"assert(code.search(/oranges:/) !== -1 && code.search(/plums:/) !== -1 && code.search(/strawberries:/) !== -1, 'message: The <code>oranges</code>, <code>plums</code>, and <code>strawberries</code> keys are removed using <code>delete</code>');"
],
"type": "waypoint",
"releasedOn": "Feb 17, 2017",
"solutions": [],
"challengeType": 1,
"translations": {}
},
{
"id": "587d7b7d367417b2b2512b1c",
"title": "Check if an Object has a Property",
"description": [
"Now we can add, modify, and remove keys from objects. But what if we just wanted to know if an object has a specific property? JavaScript provides us with two different ways to do this. One uses the <code>hasOwnProperty()</code> method and the other uses the <code>in</code> keyword. If we have an object <code>users</code> with a property of <code>Alan</code>, we could check for its presence in either of the following ways:",
"<blockquote>users.hasOwnProperty('Alan');<br>'Alan' in users;<br>// both return true</blockquote>",
"<hr>",
"We've created an object, <code>users</code>, with some users in it and a function <code>isEveryoneHere</code>, which we pass the <code>users</code> object to as an argument. Finish writing this function so that it returns <code>true</code> only if the <code>users</code> object contains all four names, <code>Alan</code>, <code>Jeff</code>, <code>Sarah</code>, and <code>Ryan</code>, as keys, and <code>false</code> otherwise."
],
"challengeSeed": [
"let users = {",
" Alan: {",
" age: 27,",
" online: true",
" },",
" Jeff: {",
" age: 32,",
" online: true",
" },",
" Sarah: {",
" age: 48,",
" online: true",
" },",
" Ryan: {",
" age: 19,",
" online: true",
" }",
"};",
"",
"function isEveryoneHere(obj) {",
" // change code below this line",
"",
" // change code above this line",
"}",
"",
"console.log(isEveryoneHere(users));"
],
"tests": [
"assert('Alan' in users && 'Jeff' in users && 'Sarah' in users && 'Ryan' in users && Object.keys(users).length === 4, 'message: The <code>users</code> object only contains the keys <code>Alan</code>, <code>Jeff</code>, <code>Sarah</code>, and <code>Ryan</code>');",
"assert(isEveryoneHere(users) === true, 'message: The function <code>isEveryoneHere</code> returns <code>true</code> if <code>Alan</code>, <code>Jeff</code>, <code>Sarah</code>, and <code>Ryan</code> are properties on the <code>users</code> object');",
"assert((function() { delete users.Alan; delete users.Jeff; delete users.Sarah; delete users.Ryan; return isEveryoneHere(users) })() === false, 'message: The function <code>isEveryoneHere</code> returns <code>false</code> if <code>Alan</code>, <code>Jeff</code>, <code>Sarah</code>, and <code>Ryan</code> are not properties on the <code>users</code> object');"
],
"type": "waypoint",
"releasedOn": "Feb 17, 2017",
"solutions": [],
"challengeType": 1,
"translations": {}
},
{
"id": "587d7b7d367417b2b2512b1d",
"title": " Iterate Through the Keys of an Object with a for...in Statement",
"description": [
"Sometimes you may need to iterate through all the keys within an object. This requires a specific syntax in JavaScript called a <dfn>for...in</dfn> statement. For our <code>users</code> object, this could look like:",
"<blockquote>for (let user in users) {<br> console.log(user);<br>};<br><br>// logs:<br>Alan<br>Jeff<br>Sarah<br>Ryan</blockquote>",
"In this statement, we defined a variable <code>user</code>, and as you can see, this variable was reset during each iteration to each of the object's keys as the statement looped through the object, resulting in each user's name being printed to the console.",
"<strong>NOTE:</strong><br>Objects do not maintain an ordering to stored keys like arrays do; thus a keys position on an object, or the relative order in which it appears, is irrelevant when referencing or accessing that key.",
"<hr>",
"We've defined a function, <code>countOnline</code>; use a <dfn>for...in</dfn> statement within this function to loop through the users in the <code>users</code> object and return the number of users whose <code>online</code> property is set to <code>true</code>."
],
"challengeSeed": [
"let users = {",
" Alan: {",
" age: 27,",
" online: false",
" },",
" Jeff: {",
" age: 32,",
" online: true",
" },",
" Sarah: {",
" age: 48,",
" online: false",
" },",
" Ryan: {",
" age: 19,",
" online: true",
" }",
"};",
"",
"function countOnline(obj) {",
" // change code below this line",
"",
" // change code above this line",
"}",
"",
"console.log(countOnline(users));"
],
"tests": [
"assert(users.Alan.online === false && users.Jeff.online === true && users.Sarah.online === false && users.Ryan.online === true, 'message: The <code>users</code> object contains users <code>Jeff</code> and <code>Ryan</code> with <code>online</code> set to <code>true</code> and users <code>Alan</code> and <code>Sarah</code> with <code>online</code> set to <code>false</code>');",
"assert((function() { users.Harry = {online: true}; users.Sam = {online: true}; users.Carl = {online: true}; return countOnline(users) })() === 5, 'message: The function <code>countOnline</code> returns the number of users with the <code>online</code> property set to <code>true</code>');"
],
"type": "waypoint",
"releasedOn": "Feb 17, 2017",
"solutions": [],
"challengeType": 1,
"translations": {}
},
{
"id": "587d7b7d367417b2b2512b1e",
"title": "Generate an Array of All Object Keys with Object.keys()",
"description": [
"We can also generate an array which contains all the keys stored in an object using the <code>Object.keys()</code> method and passing in an object as the argument. This will return an array with strings representing each property in the object. Again, there will be no specific order to the entries in the array.",
"<hr>",
"Finish writing the <code>getArrayOfUsers</code> function so that it returns an array containing all the properties in the object it receives as an argument."
],
"challengeSeed": [
"let users = {",
" Alan: {",
" age: 27,",
" online: false",
" },",
" Jeff: {",
" age: 32,",
" online: true",
" },",
" Sarah: {",
" age: 48,",
" online: false",
" },",
" Ryan: {",
" age: 19,",
" online: true",
" }",
"};",
"",
"function getArrayOfUsers(obj) {",
" // change code below this line",
"",
" // change code above this line",
"}",
"",
"console.log(getArrayOfUsers(users));"
],
"tests": [
"assert('Alan' in users && 'Jeff' in users && 'Sarah' in users && 'Ryan' in users && Object.keys(users).length === 4, 'message: The <code>users</code> object only contains the keys <code>Alan</code>, <code>Jeff</code>, <code>Sarah</code>, and <code>Ryan</code>');",
"assert((function() { users.Sam = {}; users.Lewis = {}; let R = getArrayOfUsers(users); return (R.indexOf('Alan') !== -1 && R.indexOf('Jeff') !== -1 && R.indexOf('Sarah') !== -1 && R.indexOf('Ryan') !== -1 && R.indexOf('Sam') !== -1 && R.indexOf('Lewis') !== -1); })() === true, 'message: The <code>getArrayOfUsers</code> function returns an array which contains all the keys in the <code>users</code> object');"
],
"type": "waypoint",
"releasedOn": "Feb 17, 2017",
"solutions": [],
"challengeType": 1,
"translations": {}
},
{
"id": "587d7b7d367417b2b2512b1f",
"title": "Modify an Array Stored in an Object",
"description": [
"Now you've seen all the basic operations for JavaScript objects. You can add, modify, and remove key-value pairs, check if keys exist, and iterate over all the keys in an object. As you continue learning JavaScript you will see even more versatile applications of objects. Additionally, the optional Advanced Data Structures lessons later in the curriculum also cover the ES6 <dfn>Map</dfn> and <dfn>Set</dfn> objects, both of which are similar to ordinary objects but provide some additional features. Now that you've learned the basics of arrays and objects, you're fully prepared to begin tackling more complex problems using JavaScript!",
"<hr>",
"Take a look at the object we've provided in the code editor. The <code>user</code> object contains three keys. The <code>data</code> key contains four keys, one of which contains an array of <code>friends</code>. From this, you can see how flexible objects are as data structures. We've started writing a function <code>addFriend</code>. Finish writing it so that it takes a <code>user</code> object and adds the name of the <code>friend</code> argument to the array stored in <code>user.data.friends</code> and returns that array."
],
"challengeSeed": [
"let user = {",
" name: 'Kenneth',",
" age: 28,",
" data: {",
" username: 'kennethCodesAllDay',",
" joinDate: 'March 26, 2016',",
" organization: 'freeCodeCamp',",
" friends: [",
" 'Sam',",
" 'Kira',",
" 'Tomo'",
" ],",
" location: {",
" city: 'San Francisco',",
" state: 'CA',",
" country: 'USA'",
" }",
" }",
"};",
"",
"function addFriend(userObj, friend) {",
" // change code below this line ",
"",
" // change code above this line",
"}",
"",
"console.log(addFriend(user, 'Pete'));"
],
"tests": [
"assert('name' in user && 'age' in user && 'data' in user, 'message: The <code>user</code> object has <code>name</code>, <code>age</code>, and <code>data</code> keys');",
"assert((function() { let L1 = user.data.friends.length; addFriend(user, 'Sean'); let L2 = user.data.friends.length; return (L2 === L1 + 1); })(), 'message: The <code>addFriend</code> function accepts a <code>user</code> object and a <code>friend</code> string as arguments and adds the friend to the array of <code>friends</code> in the <code>user</code> object');",
"assert.deepEqual((function() { delete user.data.friends; user.data.friends = ['Sam', 'Kira', 'Tomo']; return addFriend(user, 'Pete') })(), ['Sam', 'Kira', 'Tomo', 'Pete'], 'message: <code>addFriend(user, \"Pete\")</code> should return <code>[\"Sam\", \"Kira\", \"Tomo\", \"Pete\"]</code>');"
],
"type": "waypoint",
"releasedOn": "Feb 17, 2017",
"solutions": [],
"challengeType": 1,
"translations": {}
}
]
}

View File

@@ -0,0 +1,240 @@
{
"name": "Claim Your JavaScript Algorithms and Data Structures Certificate",
"order": 13,
"time": "5 minutes",
"challenges": [
{
"id": "587d7b7f367417b2b2512b25",
"title": "Claim Your JavaScript Algorithms and Data Structures Certificate",
"description": [
[
"//i.imgur.com/k8btNUB.jpg",
"An image of our Front End Development Certificate",
"This challenge will give you your verified Front End Development Certificate. Before we issue your certificate, we must verify that you have completed all of our basic and intermediate algorithm scripting challenges, and all our basic, intermediate, and advanced front end development projects. You must also accept our Academic Honesty Pledge. Click the button below to start this process.",
""
],
[
"//i.imgur.com/uLPsUko.jpg",
"The definition of plagiarism: Plagiarism (noun) - copying someone elses work and presenting it as your own without crediting them",
"By clicking below, you pledge that all of your submitted code A) is code you or your pair personally wrote, or B) comes from open source libraries like jQuery, or C) has been clearly attributed to its original authors. You also give us permission to audit your challenge solutions and revoke your certificate if we discover evidence of plagiarism.",
"#"
],
[
"//i.imgur.com/UedoV2G.jpg",
"An image of the text \"Front End Development Certificate requirements\"",
"Let's confirm that you have completed all of our basic and intermediate algorithm scripting challenges, and all our basic, intermediate, and advanced front end development projects. Click the button below to verify this.",
"#"
],
[
"//i.imgur.com/Q5Za9U6.jpg",
"An image of the word \"Congratulations\"",
"Congratulations! We've added your Front End Development Certificate to your portfolio page. Unless you choose to hide your solutions, this certificate will remain publicly visible and verifiable.",
""
]
],
"challengeSeed": [
{
"properties": [
"isHonest",
"isFrontEndCert"
],
"apis": [
"/certificate/honest",
"/certificate/verify/front-end"
],
"stepIndex": [
1,
2
]
}
],
"tests": [
{
"id": "a202eed8fc186c8434cb6d61",
"title": "Reverse a String"
},
{
"id": "a302f7aae1aa3152a5b413bc",
"title": "Factorialize a Number"
},
{
"id": "aaa48de84e1ecc7c742e1124",
"title": "Check for Palindromes"
},
{
"id": "a26cbbe9ad8655a977e1ceb5",
"title": "Find the Longest Word in a String"
},
{
"id": "ab6137d4e35944e21037b769",
"title": "Title Case a Sentence"
},
{
"id": "a789b3483989747d63b0e427",
"title": "Return Largest Numbers in Arrays"
},
{
"id": "acda2fb1324d9b0fa741e6b5",
"title": "Confirm the Ending"
},
{
"id": "afcc8d540bea9ea2669306b6",
"title": "Repeat a string repeat a string"
},
{
"id": "ac6993d51946422351508a41",
"title": "Truncate a string"
},
{
"id": "a9bd25c716030ec90084d8a1",
"title": "Chunky Monkey"
},
{
"id": "579e2a2c335b9d72dd32e05c",
"title": "Splice and Slice"
},
{
"id": "af2170cad53daa0770fabdea",
"title": "Mutations"
},
{
"id": "adf08ec01beb4f99fc7a68f2",
"title": "Falsy Bouncer"
},
{
"id": "a39963a4c10bc8b4d4f06d7e",
"title": "Seek and Destroy"
},
{
"id": "a24c1a4622e3c05097f71d67",
"title": "Where do I belong"
},
{
"id": "a3566b1109230028080c9345",
"title": "Sum All Numbers in a Range"
},
{
"id": "a5de63ebea8dbee56860f4f2",
"title": "Diff Two Arrays"
},
{
"id": "a7f4d8f2483413a6ce226cac",
"title": "Roman Numeral Converter"
},
{
"id": "a8e512fbe388ac2f9198f0fa",
"title": "Wherefore art thou"
},
{
"id": "a0b5010f579e69b815e7c5d6",
"title": "Search and Replace"
},
{
"id": "aa7697ea2477d1316795783b",
"title": "Pig Latin"
},
{
"id": "afd15382cdfb22c9efe8b7de",
"title": "DNA Pairing"
},
{
"id": "af7588ade1100bde429baf20",
"title": "Missing letters"
},
{
"id": "a77dbc43c33f39daa4429b4f",
"title": "Boo who"
},
{
"id": "a105e963526e7de52b219be9",
"title": "Sorted Union"
},
{
"id": "a6b0bb188d873cb2c8729495",
"title": "Convert HTML Entities"
},
{
"id": "a103376db3ba46b2d50db289",
"title": "Spinal Tap Case"
},
{
"id": "a5229172f011153519423690",
"title": "Sum All Odd Fibonacci Numbers"
},
{
"id": "a3bfc1673c0526e06d3ac698",
"title": "Sum All Primes"
},
{
"id": "ae9defd7acaf69703ab432ea",
"title": "Smallest Common Multiple"
},
{
"id": "a6e40f1041b06c996f7b2406",
"title": "Finders Keepers"
},
{
"id": "a5deed1811a43193f9f1c841",
"title": "Drop it"
},
{
"id": "ab306dbdcc907c7ddfc30830",
"title": "Steamroller"
},
{
"id": "a8d97bd4c764e91f9d2bda01",
"title": "Binary Agents"
},
{
"id": "a10d2431ad0c6a099a4b8b52",
"title": "Everything Be True"
},
{
"id": "a97fd23d9b809dac9921074f",
"title": "Arguments Optional"
},
{
"id": "56533eb9ac21ba0edf2244e2",
"title": "Caesars Cipher"
},
{
"id": "a2f1d72d9b908d0bd72bb9f6",
"title": "Make a Person"
},
{
"id": "af4afb223120f7348cdfc9fd",
"title": "Map the Debris"
}
],
"type": "Waypoint",
"challengeType": 7,
"descriptionEs": [
[
"//i.imgur.com/k8btNUB.jpg",
"Una imagen que muestra nuestro certificado de Desarrollo de interfaces",
"Este desafío te otorga tu certificado autenticado de Desarrollo de interfaces. Antes de que podamos emitir tu certificado, debemos verificar que has completado todos los desafíos básicos e intermedios de diseño de algoritmos, y todos los proyectos básicos e intermedios de desarrollo de interfaces. También debes aceptar nuestro Juramento de honestidad académica. Pulsa el botón siguiente para iniciar este proceso.",
""
],
[
"//i.imgur.com/HArFfMN.jpg",
"Plagio (nombre): acción y efecto de plagiar. Plagiar (verbo) - copiar en lo sustancial obras ajenas, dándolas como propias.",
"Al pulsar el botón siguiente, juras que todo el código en tus soluciones a los desafíos A) es código que tú o tu compañero escribieron personalmente, o B) proviene de librerías de código abierto como jQuery, o C) ha sido claramente atribuido a sus autores originales. También nos otorgas el permiso para auditar tus soluciones a los desafíos y revocar tu certificado si encontramos evidencia de plagio.",
"#"
],
[
"//i.imgur.com/14F2Van.jpg",
"Una imagen del texto \"Front End Development Certificate requirements\"",
"Confirmemos que has completado todos nuestros desafíos básicos e intermedios de diseño de algoritmos, y todos nuestros proyectos básicos e intermedios de desarrollo de interfaces. Pulsa el botón siguiente para hacer la verificación.",
"#"
],
[
"//i.imgur.com/16SIhHO.jpg",
"Una imagen de la palabra \"Congratulations\"",
"¡Felicitaciones! Hemos agregado tu certificado de Desarrollo de interfaces a tu portafolio. A menos que elijas no mostrar tus soluciones, este certificado será públicamente visible y verificable.",
""
]
],
"titleEs": "Reclama tu certificado de Desarrollo de interfaces"
}
]
}

View File

@@ -0,0 +1,386 @@
{
"name": "Debugging",
"order": 4,
"time": "1 hour",
"helpRoom": "Help",
"challenges": [
{
"id": "587d7b83367417b2b2512b32",
"title": "Introduction to the Debugging Challenges",
"description": [
[
"http://imgs.xkcd.com/comics/debugging.png",
"XKCD web comic walking through the convoluted process of debugging. The programmer moves from a browser problem, to a keyboard driver issue, receives a cryptic system utility error message, and ends by finding the sword of Martin the Warrior.",
"Debugging is a valuable and (unfortunately) necessary tool for programmers. It follows the testing phase of checking if your code works as intended, and discovering it does not. Debugging is the process of finding exactly what isn't working and fixing it.",
""
],
[
"",
"",
"After spending time creating a brilliant block of code, it is tough realizing it may have errors. These issues generally come in three forms: 1) syntax errors that prevent a program from running, 2) runtime errors when code fails to execute or has unexpected behavior, and 3) semantic (or logical) errors when code doesn't do what it's meant to.<br><br>Modern code editors (and experience) can help identify syntax errors. Semantic and runtime errors are harder to find. They may cause your program to crash, make it run forever, or give incorrect output. Think of debugging as trying to understand why your code is behaving the way it is.<br><br>Example of a syntax error - often detected by the code editor:<br><br><blockquote>funtion willNotWork( {<br>&nbsp;&nbsp;console.log(\"Yuck\");<br>}<br>// \"function\" keyword is misspelled and there's a missing parenthesis</blockquote><br><br>Here's an example of a runtime error - often detected while the program executes:<br><br><blockquote>function loopy() {<br>&nbsp;&nbsp;while(true) {<br>&nbsp;&nbsp;&nbsp;&nbsp;console.log(\"Hello, world!\");<br>&nbsp;&nbsp;}<br>}<br>// Calling loopy starts an infinite loop, which may crash your browser</blockquote><br><br>Example of a semantic error - often detected after testing code output:<br><br><blockquote>function calcAreaOfRect(w, h) {<br>&nbsp;&nbsp;return w + h; // This should be w * h<br>}<br>let myRectArea = calcAreaOfRect(2, 3);<br>// Correct syntax and the program executes, but this gives the wrong answer</blockquote>",
""
],
[
"",
"",
"Debugging is frustrating, but it helps to develop (and follow) a step-by-step approach to review your code. This means checking the intermediate values and types of variables to see if they are what they should be. You can start with a simple process of elimination.<br><br>For example, if function A works and returns what it's supposed to, then function B may have the issue. Or start checking values in a block of code from the middle to try to cut the search space in half. A problem in one spot indicates a bug in the first half of the code. If not, it's likely in the second.<br><br>This section will cover a couple helpful tools to find bugs, and some of the common forms they take. Fortunately, debugging is a learnable skill that just requires a little patience and practice to master.",
""
]
],
"releasedOn": "Feb 17, 2017",
"challengeSeed": [],
"tests": [],
"type": "waypoint",
"challengeType": 7,
"isRequired": false,
"translations": {}
},
{
"id": "587d7b83367417b2b2512b33",
"title": "Use the JavaScript Console to Check the Value of a Variable",
"description": [
"Both Chrome and Firefox have excellent JavaScript consoles, also known as DevTools, for debugging your JavaScript.",
"You can find Developer tools in your Chrome's menu or Web Console in FireFox's menu. If you're using a different browser, or a mobile phone, we strongly recommend switching to desktop Firefox or Chrome.",
"The <code>console.log()</code> method, which \"prints\" the output of what's within its parentheses to the console, will likely be the most helpful debugging tool. Placing it at strategic points in your code can show you the intermediate values of variables. It's good practice to have an idea of what the output should be before looking at what it is. Having check points to see the status of your calculations throughout your code will help narrow down where the problem is.",
"Here's an example to print 'Hello world!' to the console:",
"<code>console.log('Hello world!');</code>",
"<hr>",
"Use the <code>console.log()</code> method to print the value of the variable <code>a</code> where noted in the code."
],
"challengeSeed": [
"let a = 5;",
"let b = 1;",
"a++;",
"// Add your code below this line",
"",
"",
"let sumAB = a + b;",
"console.log(sumAB);"
],
"tests": [
"assert(code.match(/console\\.log\\(a\\)/g), 'message: Your code should use <code>console.log()</code> to check the value of the variable <code>a</code>.');"
],
"solutions": [],
"hints": [],
"type": "waypoint",
"releasedOn": "Feb 17, 2017",
"challengeType": 1,
"translations": {}
},
{
"id": "587d7b84367417b2b2512b34",
"title": "Use typeof to Check the Type of a Variable",
"description": [
"You can use <code>typeof</code> to check the data structure, or type, of a variable. This is useful in debugging when working with multiple data types. If you think you're adding two numbers, but one is actually a string, the results can be unexpected. Type errors can lurk in calculations or function calls. Especially take care when you're accessing and working with external data in the form of a JavaScript object (JSON).",
"Here are some examples using <code>typeof</code>:",
"<blockquote>console.log(typeof \"\"); // outputs \"string\"<br>console.log(typeof 0); // outputs \"number\"<br>console.log(typeof []); // outputs \"object\"<br>console.log(typeof {}); // outputs \"object\"</blockquote>",
"JavaScript recognizes six primitive (immutable) data types: <code>Boolean</code>, <code>Null</code>, <code>Undefined</code>, <code>Number</code>, <code>String</code>, and <code>Symbol</code> (new with ES6) and one type for mutable items: <code>Object</code>. Note that in JavaScript, arrays are technically a type of object.",
"<hr>",
"Add two <code>console.log()</code> statements to check the <code>typeof</code> each of the two variables <code>seven</code> and <code>three</code> in the code."
],
"challengeSeed": [
"let seven = 7;",
"let three = \"3\";",
"console.log(seven + three);",
"// Add your code below this line",
""
],
"tests": [
"assert(code.match(/console\\.log\\(typeof[\\( ].*\\)?\\);/g).length == 2, 'message: Your code should use <code>typeof</code> in two <code>console.log()</code> statements to check the type of the variables.');",
"assert(code.match(/typeof[\\( ]seven\\)?/g), 'message: Your code should use <code>typeof</code> to check the type of the variable <code>seven</code>.');",
"assert(code.match(/typeof[\\( ]three\\)?/g), 'message: Your code should use <code>typeof</code> to check the type of the variable <code>three</code>.');"
],
"solutions": [],
"hints": [],
"type": "waypoint",
"releasedOn": "Feb 17, 2017",
"challengeType": 1,
"translations": {}
},
{
"id": "587d7b84367417b2b2512b35",
"title": "Catch Misspelled Variable and Function Names",
"description": [
"The <code>console.log()</code> and <code>typeof</code> methods are the two primary ways to check intermediate values and types of program output. Now it's time to get into the common forms that bugs take. One syntax-level issue that fast typers can commiserate with is the humble spelling error.",
"Transposed, missing, or mis-capitalized characters in a variable or function name will have the browser looking for an object that doesn't exist - and complain in the form of a reference error. JavaScript variable and function names are case-sensitive.",
"<hr>",
"Fix the two spelling errors in the code so the <code>netWorkingCapital</code> calculation works."
],
"challengeSeed": [
"let receivables = 10;",
"let payables = 8;",
"let netWorkingCapital = recievables - payable;",
"console.log(`Net working capital is: ${netWorkingCapital}`);"
],
"tests": [
"assert(netWorkingCapital === 2, 'message: Check the spelling of the two variables used in the netWorkingCapital calculation, the console output should show that \"Net working capital is: 2\".');",
"assert(!code.match(/recievables/g), 'message: There should be no instances of mis-spelled variables in the code.');",
"assert(code.match(/receivables/g).length == 2, 'message: The <code>receivables</code> variable should be declared and used properly in the code.');",
"assert(!code.match(/payable;/g), 'message: There should be no instances of mis-spelled variables in the code.');",
"assert(code.match(/payables/g).length == 2, 'message: The <code>payables</code> variable should be declared and used properly in the code.');"
],
"solutions": [],
"hints": [],
"type": "waypoint",
"releasedOn": "Feb 17, 2017",
"challengeType": 1,
"translations": {}
},
{
"id": "587d7b84367417b2b2512b36",
"title": "Catch Unclosed Parentheses, Brackets, Braces and Quotes",
"description": [
"Another syntax error to be aware of is that all opening parentheses, brackets, curly braces, and quotes have a closing pair. Forgetting a piece tends to happen when you're editing existing code and inserting items with one of the pair types. Also, take care when nesting code blocks into others, such as adding a callback function as an argument to a method.",
"One way to avoid this mistake is as soon as the opening character is typed, immediately include the closing match, then move the cursor back between them and continue coding. Fortunately, most modern code editors generate the second half of the pair automatically.",
"<hr>",
"Fix the two pair errors in the code."
],
"challengeSeed": [
"let myArray = [1, 2, 3;",
"let arraySum = myArray.reduce((previous, current => previous + current);",
"console.log(`Sum of array values is: ${arraySum}`);"
],
"tests": [
"assert(code.match(/myArray\\s*?=\\s*?\\[\\s*?1\\s*?,\\s*?2\\s*?,\\s*?3\\s*?\\];/g), 'message: Your code should fix the missing piece of the array.');",
"assert(arraySum === 6, 'message: Your code should fix the missing piece of the <code>.reduce()</code> method. The console output should show that \"Sum of array values is: 6\".');"
],
"solutions": [],
"hints": [],
"type": "waypoint",
"releasedOn": "Feb 17, 2017",
"challengeType": 1,
"translations": {}
},
{
"id": "587d7b84367417b2b2512b37",
"title": "Catch Mixed Usage of Single and Double Quotes",
"description": [
"JavaScript allows the use of both single ('') and double (\"\") quotes to declare a string. Deciding which one to use generally comes down to personal preference, with some exceptions.",
"Having two choices is great when a string has contractions or another piece of text that's in quotes. Just be careful that you don't close the string too early, which causes a syntax error.",
"Here are some examples of mixing quotes:",
"<blockquote>// These are correct:<br>const grouchoContraction = \"I've had a perfectly wonderful evening, but this wasn't it.\";<br>const quoteInString = \"Groucho Marx once said 'Quote me as saying I was mis-quoted.'\";<br>// This is incorrect:<br>const uhOhGroucho = 'I've had a perfectly wonderful evening, but this wasn't it.';</blockquote>",
"Of course, it is okay to use only one style of quotes. You can escape the quotes inside the string by using the backslash (\\) escape character:",
"<blockquote>// Correct use of same quotes:<br>const allSameQuotes = 'I\\'ve had a perfectly wonderful evening, but this wasn\\'t it.';</blockquote>",
"<hr>",
"Fix the string so it either uses different quotes for the <code>href</code> value, or escape the existing ones. Keep the double quote marks around the entire string."
],
"challengeSeed": [
"let innerHtml = \"<p>Click here to <a href=\"#Home\">return home</a></p>\";",
"console.log(innerHtml);"
],
"tests": [
"assert(code.match(/<a href=\\s*?('|\\\\\")#Home\\1\\s*?>/g), 'message: Your code should fix the quotes around the <code>href</code> value \"#Home\" by either changing or escaping them.');",
"assert(code.match(/\"<p>.*?<\\/p>\";/g), 'message: Your code should keep the double quotes around the entire string.');"
],
"solutions": [],
"hints": [],
"type": "waypoint",
"releasedOn": "Feb 17, 2017",
"challengeType": 1,
"translations": {}
},
{
"id": "587d7b85367417b2b2512b38",
"title": "Catch Use of Assignment Operator Instead of Equality Operator",
"description": [
"Branching programs, i.e. ones that do different things if certain conditions are met, rely on <code>if</code>, <code>else if</code>, and <code>else</code> statements in JavaScript. The condition sometimes takes the form of testing whether a result is equal to a value.",
"This logic is spoken (in English, at least) as \"if x equals y, then ...\" which can literally translate into code using the <code>=</code>, or assignment operator. This leads to unexpected control flow in your program.",
"As covered in previous challenges, the assignment operator (<code>=</code>) in JavaScript assigns a value to a variable name. And the <code>==</code> and <code>===</code> operators check for equality (the triple <code>===</code> tests for strict equality, meaning both value and type are the same).",
"The code below assigns <code>x</code> to be 2, which evaluates as <code>true</code>. Almost every value on its own in JavaScript evaluates to <code>true</code>, except what are known as the \"falsy\" values: <code>false</code>, <code>0</code>, <code>\"\"</code> (an empty string), <code>NaN</code>, <code>undefined</code>, and <code>null</code>.",
"<blockquote>let x = 1;<br>let y = 2;<br>if (x = y) {<br>&nbsp;&nbsp;// this code block will run for any value of y (unless y were originally set as a falsy)<br>} else {<br>&nbsp;&nbsp;// this code block is what should run (but won't) in this example<br>}</blockquote>",
"<hr>",
"Fix the condition so the program runs the right branch, and the appropriate value is assigned to <code>result</code>."
],
"challengeSeed": [
"let x = 7;",
"let y = 9;",
"let result = \"to come\";",
"",
"if(x = y) {",
" result = \"Equal!\";",
"} else {",
" result = \"Not equal!\";",
"}",
"",
"console.log(result);"
],
"tests": [
"assert(result == \"Not equal!\", 'message: Your code should fix the condition so it checks for equality, instead of using assignment.');",
"assert(code.match(/x\\s*?===?\\s*?y/g), 'message: The condition can use either <code>==</code> or <code>===</code> to test for equality.');"
],
"solutions": [],
"hints": [],
"type": "waypoint",
"releasedOn": "Feb 17, 2017",
"challengeType": 1,
"translations": {}
},
{
"id": "587d7b85367417b2b2512b39",
"title": "Catch Missing Open and Closing Parenthesis After a Function Call",
"description": [
"When a function or method doesn't take any arguments, you may forget to include the (empty) opening and closing parentheses when calling it. Often times the result of a function call is saved in a variable for other use in your code. This error can be detected by logging variable values (or their types) to the console and seeing that one is set to a function reference, instead of the expected value the function returns.",
"The variables in the following example are different:",
"<blockquote>function myFunction() {<br>&nbsp;&nbsp;return \"You rock!\";<br>}<br>let varOne = myFunction; // set to equal a function<br>let varTwo = myFunction(); // set to equal the string \"You rock!\"</blockquote>",
"<hr>",
"Fix the code so the variable <code>result</code> is set to the value returned from calling the function <code>getNine</code>."
],
"challengeSeed": [
"function getNine() {",
" let x = 6;",
" let y = 3;",
" return x + y;",
"}",
"",
"let result = getNine;",
"console.log(result);"
],
"tests": [
"assert(result == 9, 'message: Your code should fix the variable <code>result</code> so it is set to the number that the function <code>getNine</code> returns.');",
"assert(code.match(/getNine\\(\\)/g).length == 2, 'message: Your code should call the <code>getNine</code> function.');"
],
"solutions": [],
"hints": [],
"type": "waypoint",
"releasedOn": "Feb 17, 2017",
"challengeType": 1,
"translations": {}
},
{
"id": "587d7b85367417b2b2512b3a",
"title": "Catch Arguments Passed in the Wrong Order When Calling a Function",
"description": [
"Continuing the discussion on calling functions, the next bug to watch out for is when a function's arguments are supplied in the incorrect order. If the arguments are different types, such as a function expecting an array and an integer, this will likely throw a runtime error. If the arguments are the same type (all integers, for example), then the logic of the code won't make sense. Make sure to supply all required arguments, in the proper order to avoid these issues.",
"<hr>",
"The function <code>raiseToPower</code> raises a base to an exponent. Unfortunately, it's not called properly - fix the code so the value of <code>power</code> is the expected 8."
],
"challengeSeed": [
"function raiseToPower(b, e) {",
" return Math.pow(b, e);",
"}",
"",
"let base = 2;",
"let exp = 3;",
"let power = raiseToPower(exp, base);",
"console.log(power);"
],
"tests": [
"assert(power == 8, 'message: Your code should fix the variable <code>power</code> so it equals 2 raised to the 3rd power, not 3 raised to the 2nd power.');",
"assert(code.match(/raiseToPower\\(\\s*?base\\s*?,\\s*?exp\\s*?\\);/g), 'message: Your code should use the correct order of the arguments for the <code>raiseToPower</code> function call.');"
],
"solutions": [],
"hints": [],
"type": "waypoint",
"releasedOn": "Feb 17, 2017",
"challengeType": 1,
"translations": {}
},
{
"id": "587d7b86367417b2b2512b3b",
"title": "Catch Off By One Errors When Using Indexing",
"description": [
"<code>Off by one errors</code> (sometimes called OBOE) crop up when you're trying to target a specific index of a string or array (to slice or access a segment), or when looping over the indices of them. JavaScript indexing starts at zero, not one, which means the last index is always one less than the length of the item. If you try to access an index equal to the length, the program may throw an \"index out of range\" reference error or print <code>undefined</code>.",
"When you use string or array methods that take index ranges as arguments, it helps to read the documentation and understand if they are inclusive (the item at the given index is part of what's returned) or not. Here are some examples of off by one errors:",
"<blockquote>let alphabet = \"abcdefghijklmnopqrstuvwxyz\";<br>let len = alphabet.length;<br>for (let i = 0; i <= len; i++) {<br>&nbsp;&nbsp;// loops one too many times at the end<br>&nbsp;&nbsp;console.log(alphabet[i]);<br>}<br>for (let j = 1; j < len; j++) {<br>&nbsp;&nbsp;// loops one too few times and misses the first character at index 0<br>&nbsp;&nbsp;console.log(alphabet[j]);<br>}<br>for (let k = 0; k < len; k++) {<br>&nbsp;&nbsp;// Goldilocks approves - this is just right<br>&nbsp;&nbsp;console.log(alphabet[k]);<br>}</blockquote>",
"<hr>",
"Fix the two indexing errors in the following function so all the numbers 1 through 5 are printed to the console."
],
"challengeSeed": [
"function countToFive() {",
" let firstFive = \"12345\";",
" let len = firstFive.length;",
" // Fix the line below",
" for (let i = 1; i <= len; i++) {",
" // Do not alter code below this line",
" console.log(firstFive[i]);",
" }",
"}",
"",
"countToFive();"
],
"tests": [
"assert(code.match(/i\\s*?=\\s*?0\\s*?;/g).length == 1, 'message: Your code should set the initial condition of the loop so it starts at the first index.');",
"assert(!code.match(/i\\s?=\\s*?1\\s*?;/g), 'message: Your code should fix the initial condition of the loop so that the index starts at 0.');",
"assert(code.match(/i\\s*?<\\s*?len\\s*?;/g).length == 1, 'message: Your code should set the terminal condition of the loop so it stops at the last index.');",
"assert(!code.match(/i\\s*?<=\\s*?len;/g), 'message: Your code should fix the terminal condition of the loop so that it stops at 1 before the length.');"
],
"solutions": [],
"hints": [],
"type": "waypoint",
"releasedOn": "Feb 17, 2017",
"challengeType": 1,
"translations": {}
},
{
"id": "587d7b86367417b2b2512b3c",
"title": "Use Caution When Reinitializing Variables Inside a Loop",
"description": [
"Sometimes it's necessary to save information, increment counters, or re-set variables within a loop. A potential issue is when variables either should be reinitialized, and aren't, or vice versa. This is particularly dangerous if you accidentally reset the variable being used for the terminal condition, causing an infinite loop.",
"Printing variable values with each cycle of your loop by using <code>console.log()</code> can uncover buggy behavior related to resetting, or failing to reset a variable.",
"<hr>",
"The following function is supposed to create a two-dimensional array with <code>m</code> rows and <code>n</code> columns of zeroes. Unfortunately, it's not producing the expected output because the <code>row</code> variable isn't being reinitialized (set back to an empty array) in the outer loop. Fix the code so it returns a correct 3x2 array of zeroes, which looks like <code>[[0, 0], [0, 0], [0, 0]]</code>."
],
"challengeSeed": [
"function zeroArray(m, n) {",
" // Creates a 2-D array with m rows and n columns of zeroes",
" let newArray = [];",
" let row = [];",
" for (let i = 0; i < m; i++) {",
" // Adds the m-th row into newArray",
" ",
" for (let j = 0; j < n; j++) {",
" // Pushes n zeroes into the current row to create the columns",
" row.push(0);",
" }",
" // Pushes the current row, which now has n zeroes in it, to the array",
" newArray.push(row);",
" }",
" return newArray;",
"}",
"",
"let matrix = zeroArray(3, 2);",
"console.log(matrix);"
],
"tests": [
"assert(JSON.stringify(matrix) == \"[[0,0],[0,0],[0,0]]\", 'message: Your code should set the <code>matrix</code> variable to an array holding 3 rows of 2 columns of zeroes each.');",
"assert(matrix.length == 3, 'message: The <code>matrix</code> variable should have 3 rows.');",
"assert(matrix[0].length == 2 && matrix[1].length === 2 && matrix[2].length === 2, 'message: The <code>matrix</code> variable should have 2 columns in each row.');"
],
"solutions": [],
"hints": [],
"type": "waypoint",
"releasedOn": "Feb 17, 2017",
"challengeType": 1,
"translations": {}
},
{
"id": "587d7b86367417b2b2512b3d",
"title": "Prevent Infinite Loops with a Valid Terminal Condition",
"description": [
"The final topic is the dreaded infinite loop. Loops are great tools when you need your program to run a code block a certain number of times or until a condition is met, but they need a terminal condition that ends the looping. Infinite loops are likely to freeze or crash the browser, and cause general program execution mayhem, which no one wants.",
"There was an example of an infinite loop in the introduction to this section - it had no terminal condition to break out of the <code>while</code> loop inside <code>loopy()</code>. Do NOT call this function!",
"<blockquote>function loopy() {<br>&nbsp;&nbsp;while(true) {<br>&nbsp;&nbsp;&nbsp;&nbsp;console.log(\"Hello, world!\");<br>&nbsp;&nbsp;}<br>}</blockquote>",
"It's the programmer's job to ensure that the terminal condition, which tells the program when to break out of the loop code, is eventually reached. One error is incrementing or decrementing a counter variable in the wrong direction from the terminal condition. Another one is accidentally resetting a counter or index variable within the loop code, instead of incrementing or decrementing it.",
"<hr>",
"The <code>myFunc()</code> function contains an infinite loop because the terminal condition <code>i != 4</code> will never evaluate to <code>false</code> (and break the looping) - <code>i</code> will increment by 2 each pass, and jump right over 4 since <code>i</code> is odd to start. Fix the comparison operator in the terminal condition so the loop only runs for <code>i</code> less than or equal to 4."
],
"challengeSeed": [
"function myFunc() {",
" for (let i = 1; i != 4; i += 2) {",
" console.log(\"Still going!\");",
" }",
"}"
],
"tests": [
"assert(code.match(/i\\s*?<=\\s*?4;/g).length == 1, 'message: Your code should change the comparison operator in the terminal condition (the middle part) of the <code>for</code> loop.');",
"assert(!code.match(/i\\s*?!=\\s*?4;/g), 'message: Your code should fix the comparison operator in the terminal condition of the loop.');"
],
"solutions": [],
"hints": [],
"type": "waypoint",
"releasedOn": "Feb 17, 2017",
"challengeType": 1,
"translations": {}
}
]
}

View File

@@ -0,0 +1,841 @@
{
"name": "ES6",
"order": 2,
"time": "5 hours",
"helpRoom": "Help",
"challenges": [
{
"id": "587d7b86367417b2b2512b3e",
"title": "Introduction to the ES6 Challenges",
"description": [
[
"",
"",
"ECMAScript is a standardized version of JavaScript with the goal of unifying the language's specifications and features. As all major browsers and JavaScript-runtimes follow this specification, the term <i>ECMAScript</i> is interchangeable with the term <i>JavaScript</i>.<br><br>Most of the challenges on freeCodeCamp use the ECMAScript 5 (ES5) specification of the language, finalized in 2009. But JavaScript is an evolving programming language. As features are added and revisions are made, new versions of the language are released for use by developers.<br><br>The most recent standardized version is called ECMAScript 6 (ES6), released in 2015. This new version of the language adds some powerful features that will be covered in this section of challenges, including:<br><br><ul><li>Arrow functions</li><li>Classes</li><li>Modules</li><li>Promises</li><li>Generators</li><li><code>let</code> and <code>const</code></li></ul><br><br><strong>Note</strong><br>Not all browsers support ES6 features. If you use ES6 in your own projects, you may need to use a program (transpiler) to convert your ES6 code into ES5 until browsers support ES6.",
""
]
],
"releasedOn": "Feb 17, 2017",
"challengeSeed": [],
"tests": [],
"type": "waypoint",
"challengeType": 7,
"isRequired": false,
"translations": {}
},
{
"id": "587d7b87367417b2b2512b3f",
"title": "Explore Problems with the var Keyword",
"description": [
"One of the biggest problems with declaring variables with the <code>var</code> keyword is that you can overwrite variable declarations without an error.",
"<blockquote>var camper = 'James';<br>var camper = 'David';<br>console.log(camper);<br>// logs 'David'</blockquote>",
"In a small application, you might not run into this type of problem, but when your code becomes larger, you might accidently overwrite a variable that you did not intend to overwrite. Because this behaviour does not throw an error, searching and fixing bugs becomes more difficult.",
"Another problem with the <code>var</code> keyword is that it is hoisted to the top of your code when it compiles. This means that you can use a variable before you declare it.",
"<blockquote>console.log(camper);<br>var camper = 'David';<br>// logs undefined</blockquote>",
"The code runs in the following order:",
"<ol><li>The variable <code>camper</code> is declared as undefined.</li><li>The value of <code>camper</code> is logged.</li><li>David is assigned to <code>camper</code>.</li></ol>",
"This code will run without an error.",
"A new keyword called <code>let</code> was introduced in ES6 to solve the problems with the <code>var</code> keyword. With the <code>let</code> keyword, all the examples we just saw will cause an error to appear. We can no longer overwrite variables or use a variable before we declare it. Some modern browsers require you to add <code>\"use strict\";</code> to the top of your code before you can use the new features of ES6.",
"Let's try using the <code>let</code> keyword.",
"<hr>",
"Fix the code so that it only uses the <code>let</code> keyword and makes the errors go away.",
"<strong>Note</strong><br>Remember to add <code>\"use strict\";</code> to the top of your code."
],
"challengeSeed": [
"var favorite = redNosedReindeer + \" is Santa's favorite reindeer.\";",
"var redNosedReindeer = \"Rudolph\";",
"var redNosedReindeer = \"Comet\";"
],
"tests": [
"assert(redNosedReindeer === \"Rudolph\", 'message: <code>redNosedReindeer</code> should be Rudolph.');",
"assert(favorite === \"Rudolph is Santa's favorite reindeer.\", \"message: <code>favorite</code> should return Santa's favorite reindeer.\");"
],
"type": "waypoint",
"releasedOn": "Feb 17, 2017",
"challengeType": 1,
"translations": {}
},
{
"id": "587d7b87367417b2b2512b40",
"title": "Compare Scopes of the var and let Keywords",
"description": [
"When you declare a variable with the <code>var</code> keyword, it is declared globally, or locally if declared inside a function.",
"The <code>let</code> keyword behaves similarly, but with some extra features. When you declare a variable with the <code>let</code> keyword inside a block, statement, or expression, its scope is limited to that block, statement, or expression.",
"For example:",
"<blockquote>var numArray = [];<br>for (var i = 0; i < 3; i++) {<br> numArray.push(i);<br>}<br>console.log(numArray);<br>// returns [0, 1, 2]<br>console.log(i);<br>// returns 3</blockquote>",
"With the <code>var</code> keyword, <code>i</code> is declared globally. So when <code>i++</code> is executed, it updates the global variable. This code is similiar to the following:",
"<blockquote>var numArray = [];<br>var i;<br>for (i = 0; i < 3; i++) {<br> numArray.push(i);<br>}<br>console.log(numArray);<br>// returns [0, 1, 2]<br>console.log(i);<br>// returns 3</blockquote>",
"This behavior will cause problems if you were to create a function and store it for later use inside a for loop that uses the <code>i</code> variable. This is because the stored function will always refer to the value of the updated global <code>i</code> variable.",
"<blockquote>var printNumTwo;<br>for (var i = 0; i < 3; i++) {<br> if(i === 2){<br> printNumTwo = function() {<br> return i;<br> };<br> }<br>}<br>console.log(printNumTwo());<br>// returns 3</blockquote>",
"As you can see, <code>printNumTwo()</code> prints 3 and not 2. This is because the value assigned to <code>i</code> was updated and the <code>printNumTwo()</code> returns the global <code>i</code> and not the value <code>i</code> had when the function was created in the for loop. The <code>let</code> keyword does not follow this behavior:",
"<blockquote>'use strict';<br>let printNumTwo;<br>for (let i = 0; i < 3; i++) {<br> if (i === 2) {<br> printNumTwo = function() {<br> return i;<br> };<br> }<br>}<br>console.log(printNumTwo());<br>// returns 2<br>console.log(i);<br>// returns \"i is not defined\"</blockquote>",
"<code>i</code> is not defined because it was not declared in the global scope. It is only declared within the for loop statement. <code>printNumTwo()</code> returned the correct value because three different <code>i</code> variables with unique values (0, 1, and 2) were created by the <code>let</code> keyword within the loop statement.",
"<hr>",
"Fix the code so that <code>i</code> declared in the if statement is a separate variable than <code>i</code> declared in the first line of the function. Be certain not to use the <code>var</code> keyword anywhere in your code.",
"<strong>Note</strong><br>Remember to add <code>\"use strict\";</code> to the top of your code.",
"This exercise is designed to illustrate the difference between how <code>var</code> and <code>let</code> keywords assign scope to the declared variable. When programming a function similar to the one used in this exercise, it is often better to use different variable names to avoid confusion."
],
"challengeSeed": [
"function checkScope() {",
" var i = \"function scope\";",
" if (true) {",
" i = \"block scope\";",
" console.log(\"Block scope i is: \", i);",
" }",
" console.log(\"Function scope i is: \", i);",
" return i;",
"}",
"// only change the code above this line",
"checkScope();"
],
"tests": [
"// TEMPORARILY COMMENTED OUT: assert(!/var/g.test(code) && /let/g.test(code), 'message: The <code>var</code> keyword should be replaced with <code>let</code>. (This test is temporarily disabled)');",
"assert(code.match(/(i\\s*=\\s*).*\\s*.*\\s*.*\\1('|\")block\\s*scope\\2/g), 'message: The variable <code>i</code> declared in the if statement should equal \"block scope\".');",
"assert(checkScope() === \"function scope\", 'message: <code>checkScope()</code> should return \"function scope\"');"
],
"type": "waypoint",
"releasedOn": "Feb 17, 2017",
"challengeType": 1,
"translations": {}
},
{
"id": "587d7b87367417b2b2512b41",
"title": "Declare a Read-Only Variable with the const Keyword",
"description": [
"<code>let</code> is not the only new way to declare variables. In ES6, you can also declare variables using the <code>const</code> keyword.",
"<code>const</code> has all the awesome features that <code>let</code> has, with the added bonus that variables declared using <code>const</code> are read-only. They are a constant value, which means that once a variable is assigned with <code>const</code>, it cannot be reassigned.",
"<blockquote>\"use strict\"<br>const FAV_PET = \"Cats\";<br>FAV_PET = \"Dogs\"; // returns error</blockquote>",
"As you can see, trying to reassign a variable declared with <code>const</code> will throw an error. You should always name variables you don't want to reassign using the <code>const</code> keyword. This helps when you accidentally attempt to reassign a variable that is meant to stay constant. A common practice is to name your constants in all upper-cases and with an underscore to separate words (e.g. <code>EXAMPLE_VARIABLE</code>).",
"<hr>",
"Change the code so that all variables are declared using <code>let</code> or <code>const</code>. Use <code>let</code> when you want the variable to change, and <code>const</code> when you want the variable to remain constant. Also, rename variables declared with <code>const</code> to conform to common practices.",
"<strong>Note</strong><br>Don't forget to add <code>\"use strict\";</code> to the top of your code."
],
"challengeSeed": [
"// change 'var' to 'let' or 'const'",
"// rename constant variables",
"var pi = 3.14;",
"var radius = 10;",
"var calculateCircumference = function(r) {",
" var diameter = 2 * r;",
" var result = pi * diameter;",
" return result;",
"};",
"// Test your code",
"console.log(calculateCircumference(radius));"
],
"tests": [
"// Test user replaced all var keyword",
"// Test PI is const",
"// Test calculateCircumference is const",
"// Test pi and calculateCircumference has been renamed"
],
"type": "waypoint",
"releasedOn": "Feb 17, 2017",
"challengeType": 1,
"translations": {}
},
{
"id": "587d7b87367417b2b2512b42",
"title": "Mutate an Array Declared with const",
"description": [
"The <code>const</code> declaration has many use cases in modern JavaScript.",
"Some developers prefer to assign all their variables using <code>const</code> by default, unless they know they will need to reassign the value. Only in that case, they use <code>let</code>.",
"However, it is important to understand that objects (including arrays and functions) assigned to a variable using <code>const</code> are still mutable. Using the <code>const</code> declaration only prevents reassignment of the variable identifier.",
"<blockquote>\"use strict\";<br>const s = [5, 6, 7];<br>s = [1, 2, 3]; // throws error, trying to assign a const<br>s[2] = 45; // works just as it would with an array declared with var or let<br>console.log(s); // returns [5, 6, 45]</blockquote>",
"As you can see, you can mutate the object <code>[5, 6, 7]</code> itself and the variable <code>s</code> will still point to the altered array <code>[5, 6, 45]</code>. Like all arrays, the array elements in <code>s</code> are mutable, but because <code>const</code> was used, you cannot use the variable identifier <code>s</code> to point to a different array using the assignment operator.",
"<hr>",
"An array is declared as <code>const s = [5, 7, 2]</code>. Change the array to <code>[2, 5, 7]</code> using various element assignment.",
"<strong>Note</strong><br>Don't forget to add <code>\"use strict\";</code> to the top of your code."
],
"challengeSeed": [
"const s = [5, 7, 2];",
"// change code below this line",
"",
"s = [2, 5, 7];",
"",
"// change code above this line",
"// Test your code",
"console.log(s);"
],
"tests": [
"assert(code.match(/const/g), 'message: Do not replace <code>const</code> keyword.');",
"assert(code.match(/const\\s+s/g), 'message: <code>s</code> is declared with <code>const</code>.');",
"assert(code.match(/const\\s+s\\s*?=\\s*?\\[\\s*?2\\s*?,\\s*?5\\s*?,\\s*?7\\s*?\\]\\s*?;/g), 'message: Do not change the original array declaration.');",
"assert.deepEqual(s, [2, 5, 7], 'message: <code>s</code> should be equal to <code>[2, 5, 7]</code>.');"
],
"type": "waypoint",
"releasedOn": "Feb 17, 2017",
"challengeType": 1,
"translations": {}
},
{
"id": "587d7b87367417b2b2512b43",
"title": "Use Arrow Functions to Write Concise Anonymous Functions",
"description": [
"In JavaScript, we often don't need to name our functions, especially when passing a function as an argument to another function. Instead, we create inline functions. We don't need to name these functions because we do not reuse them anywhere else.",
"To achieve this, we often use the following syntax:",
"<blockquote>const myFunc = function() {<br> const myVar = \"value\";<br> return myVar;<br>}</blockquote>",
"ES6 provides us with the syntactic sugar to not have to write anonymous functions this way. Instead, you can use <strong>arrow function syntax</strong>:",
"<blockquote>const myFunc = () => {<br> const myVar = \"value\";<br> return myVar;<br>}</blockquote>",
"When there is no function body, and only a return value, arrow function syntax allows you to omit the keyword <code>return</code> as well as the brackets surrounding the code. This helps simplify smaller functions into one-line statements:",
"<blockquote>const myFunc= () => \"value\"</blockquote>",
"This code will still return <code>value</code> by default.",
"<hr>",
"Rewrite the function assigned to the variable <code>magic</code> which returns a new <code>Date()</code> to use arrow function syntax. Also make sure nothing is defined using the keyword <code>var</code>.",
"Note",
"Don't forget to use strict mode."
],
"challengeSeed": [
"// change code below this line",
"var magic = function() {",
" return new Date();",
"}",
"// change code above this line",
"// test your code",
"console.log(magic());"
],
"tests": [
"// Test user did replace var keyword",
"// Test magic is const",
"// Test magic is a function",
"// Test magic() returns the correct date",
"// Test function keyword was not used",
"// Test arrow => was used"
],
"type": "waypoint",
"releasedOn": "Feb 17, 2017",
"challengeType": 1,
"translations": {}
},
{
"id": "587d7b88367417b2b2512b44",
"title": "Write Arrow Functions with Parameters",
"description": [
"Just like a normal function, you can pass arguments into arrow functions.",
"<blockquote>// doubles input value and returns it<br>const doubler = (item) => item * 2;</blockquote>",
"You can pass more than one argument into arrow functions as well.",
"<hr>",
"Rewrite the <code>myConcat</code> function which appends contents of <code>arr2</code> to <code>arr1</code> so that the function uses arrow function syntax.",
"Note",
"Don't forget to use strict mode."
],
"challengeSeed": [
"// change code below this line",
"var myConcat = function(arr1, arr2) {",
" return arr1.concat(arr2);",
"}",
"// change code above this line",
"// test your code",
"console.log(myConcat([1, 2], [3, 4, 5]));"
],
"tests": [
"// Test user did replace var keyword",
"// Test myConcat is const",
"assert(typeof myConcat === \"function\", 'message: <code>myConcat</code> should be a function');",
"// Test myConcat() returns the correct array",
"// Test function keyword was not used",
"// Test arrow => was used"
],
"type": "waypoint",
"releasedOn": "Feb 17, 2017",
"challengeType": 1,
"translations": {}
},
{
"id": "587d7b88367417b2b2512b45",
"title": "Write Higher Order Arrow Functions",
"description": [
"It's time we see how powerful arrow functions are when processing data.",
"Arrow functions work really well with higher order functions, such as <code>map()</code>, <code>filter()</code>, and <code>reduce()</code>, that take other functions as arguments for processing collections of data.",
"Read the following code:",
"<blockquote>FBPosts.filter(function(post) {<br> return post.thumbnail !== null && post.shares > 100 && post.likes > 500;<br>})</blockquote>",
"We have written this with <code>filter()</code> to at least make it somewhat readable. Now compare it to the following code which uses arrow function syntax instead:",
"<blockquote>FBPosts.filter((post) => post.thumbnail !== null && post.shares > 100 && post.likes > 500)</blockquote>",
"This code is more succinct and accomplishes the same task with fewer lines of code.",
"<hr>",
"Use arrow function syntax to compute the square of only the positive integers (fractions are not integers) in the array <code>realNumberArray</code> and store the new array in the variable <code>squaredIntegers</code>.",
"Note",
"Don't forget to use strict mode."
],
"challengeSeed": [
"const realNumberArray = [4, 5.6, -9.8, 3.14, 42, 6, 8.34];",
"// change code below this line",
"var squaredIntegers = realNumberArray;",
"// change code above this line",
"// test your code",
"console.log(squaredIntegers);"
],
"tests": [
"// Test user did replace <code>var</code> keyword",
"// Test <code>squaredIntegers</code> is <code>const</code>",
"assert(Array.isArray(squaredIntegers), 'message: <code>squaredIntegers</code> should be an array');",
"assert(squaredIntegers[0] === 16 && squaredIntegers[1] === 1764 && squaredIntegers[2] === 36, 'message: <code>squaredIntegers</code> should be <code>[16, 1764, 36]</code>');",
"// Test <code>function</code> keyword was not used",
"// Test arrow <code>=></code> was used",
"assert(!code.match(/(for)|(while)/g), 'message: loop should not be used');",
"assert(code.match(/map/g) && code.match(/filter/g), 'message: <code>map</code> and <code>filter</code> should be used');"
],
"type": "waypoint",
"releasedOn": "Feb 17, 2017",
"challengeType": 1,
"translations": {}
},
{
"id": "587d7b88367417b2b2512b46",
"title": "Set Default Parameters for Your Functions",
"description": [
"In order to help us create more flexible functions, ES6 introduces <dfn>default parameters</dfn> for functions.",
"Check out this code:",
"<blockquote>function greeting(name = \"Anonymous\") {<br> return \"Hello \" + name;<br>}<br>console.log(greeting(\"John\")); // Hello John<br>console.log(greeting()); // Hello Anonymous</blockquote>",
"The default parameter kicks in when the argument is not specified (it is undefined). As you can see in the example above, the parameter <code>name</code> will receive its default value <code>\"Anonymous\"</code> when you do not provide a value for the parameter. You can add default values for as many parameters as you want.",
"<hr>",
"Modify the function <code>increment</code> by adding default parameters so that it will add 1 to <code>number</code> if <code>value</code> is not specified.",
"<strong>Note</strong><br>Don't forget to use strict mode."
],
"challengeSeed": [
"function increment(number, value) {",
" return number + value;",
"}",
"console.log(increment(5, 2)); // returns 7",
"console.log(increment(5)); // returns NaN"
],
"tests": [
"assert(increment(5, 2) === 7, \"The result of increment(5, 2) should be 7\");",
"assert(increment(5) === 6, \"The result of increment(5) should be 6\");",
"// Test default parameter was used for 'value'"
],
"type": "waypoint",
"releasedOn": "Feb 17, 2017",
"challengeType": 1,
"translations": {}
},
{
"id": "587d7b88367417b2b2512b47",
"title": "Use the Rest Operator with Function Parameters",
"description": [
"In order to help us create more flexible functions, ES6 introduces the <dfn>rest operator</dfn> for function parameters. With the rest operator, you can create functions that take a variable number of arguments. These arguments are stored in an array that can be accessed later from inside the function.",
"Check out this code:",
"<blockquote>function howMany(...args) {<br> return \"You have passed \" + args.length + \" arguments.\";<br>}<br>console.log(howMany(0, 1, 2)); // You have passed 3 arguments<br>console.log(howMany(\"string\", null, [1, 2, 3], { })); // You have passed 4 arguments.</blockquote>",
"The rest operator eliminates the need to check the <code>args</code> array and allows us to apply <code>map()</code>, <code>filter()</code> and <code>reduce()</code> on the parameters array.",
"<hr>",
"Modify the function <code>sum</code> so that is uses the rest operator and it works in the same way with any number of parameters.",
"<strong>Note</strong><br>Don't forget to use strict mode."
],
"challengeSeed": [
"function sum(x, y, z) {",
" const array = [ x, y, z ];",
" return array.reduce((a, b) => a + b, 0);",
"}",
"console.log(sum(1, 2, 3)); // 6"
],
"tests": [
"assert(sum(0,1,2) === 3, 'The result of sum(0,1,2) should be 3');",
"assert(sum(1,2,3,4) === 10, 'The result of sum(1,2,3,4) should be 10');",
"assert(sum(5) === 5, 'The result of sum(5) should be 5');",
"assert(sum() === 0, 'The result of sum() should be 0');"
],
"type": "waypoint",
"releasedOn": "Feb 17, 2017",
"challengeType": 1,
"translations": {}
},
{
"id": "587d7b89367417b2b2512b48",
"title": "Use the Spread Operator to Evaluate Arrays In-Place",
"description": [
"ES6 introduces the <dfn>spread operator</dfn>, which allows us to expand arrays and other expressions in places where multiple parameters or elements are expected.",
"The ES5 code below uses <code>apply()</code> to compute the maximum value in an array:",
"<blockquote>var arr = [6, 89, 3, 45];<br>var maximus = Math.max.apply(null, arr); // returns 89</blockquote>",
"We had to use <code>Math.max.apply(null, arr)</code> because <code>Math.max(arr)</code> returns <code>NaN</code>. <code>Math.max()</code> expects comma-separated arguments, but not an array.",
"The spread operator makes this syntax much better to read and maintain.",
"<blockquote>const arr = [6, 89, 3, 45];<br>const maximus = Math.max(...arr); // returns 89</blockquote>",
"<code>...arr</code> returns an unpacked array. In other words, it <em>spreads</em> the array.",
"However, the spread operator only works in-place, like in an argument to a function or in an array literal. The following code will not work:",
"<blockquote>const spreaded = ...arr; // will throw a syntax error</blockquote>",
"<hr>",
"Copy all contents of <code>arr1</code> into another array <code>arr2</code> using the spread operator."
],
"challengeSeed": [
"const arr1 = ['JAN', 'FEB', 'MAR', 'APR', 'MAY'];",
"const arr2 = []; // change this line",
"arr1.push('JUN');",
"console.log(arr2); // arr2 should not be affected"
],
"tests": [
"// Test arr2 is correct copy of arr1",
"// Test arr1 has changed",
"// Test spread operator was used"
],
"type": "waypoint",
"releasedOn": "Feb 17, 2017",
"challengeType": 1,
"translations": {}
},
{
"id": "587d7b89367417b2b2512b49",
"title": "Use Destructuring Assignment to Assign Variables from Objects",
"description": [
"We earlier saw how spread operator can effectively spread, or unpack, the contents of the array.",
"We can do something similar with objects as well. <dfn>Destructuring assignment</dfn> is special syntax for neatly assigning values taken directly from an object to variables.",
"Consider the following ES5 code:",
"<blockquote>var voxel = {x: 3.6, y: 7.4, z: 6.54 };<br>var x = voxel.x; // x = 3.6<br>var y = voxel.y; // y = 7.4<br>var z = voxel.z; // z = 6.54</blockquote>",
"Here's the same assignment statement with ES6 destructuring syntax:",
"<blockquote>const { x, y, z } = voxel; // x = 3.6, y = 7.4, z = 6.54</blockquote>",
"If instead you want to store the values of <code>voxel.x</code> into <code>a</code>, <code>voxel.y</code> into <code>b</code>, and <code>voxel.z</code> into <code>c</code>, you have that freedom as well.",
"<blockquote>const { x : a, y : b, z : c } = voxel // a = 3.6, b = 7.4, c = 6.54</blockquote>",
"You may read it as \"get the field <code>x</code> and copy the value into <code>a</code>,\" and so on.",
"<hr>",
"Use destructuring to obtain the length of the string <code>greeting</code>"
],
"challengeSeed": [
"const greeting = 'itadakimasu';",
"// change code below this line",
"const length = 0; // change this",
"// change code above this line",
"console.log(length); // should be using destructuring"
],
"tests": [
"// Test len is 11",
"// Test destructuring was used"
],
"type": "waypoint",
"releasedOn": "Feb 17, 2017",
"challengeType": 1,
"translations": {}
},
{
"id": "587d7b89367417b2b2512b4a",
"title": "Use Destructuring Assignment to Assign Variables from Nested Objects",
"description": [
"We can similarly destructure <em>nested</em> objects into variables.",
"Consider the following code:",
"<blockquote>const a = {<br> start: { x: 5, y: 6},<br> end: { x: 6, y: -9 }<br>};<br>const { start : { x: startX, y: startY }} = a;<br>console.log(startX, startY); // 5, 6</blockquote>",
"In the example above, the variable <code>start</code> is assigned the value of <code>a.start</code>, which is also an object.",
"<hr>",
"Use destructuring assignment to obtain <code>max</code> of <code>forecast.tomorrow</code> and assign it to <code>maxOfTomorrow</code>."
],
"challengeSeed": [
"const forecast = {",
" today: { min: 72, max: 83 },",
" tomorrow: { min: 73.3, max: 84.6 }",
"};",
"// change code below this line",
"const maxOfTomorrow = undefined; // change this line",
"// change code above this line",
"console.log(maxOfTomorrow); // should be 84.6"
],
"tests": [
"// Test maxOfTomorrow to be 84.6",
"// Test destructuring was used"
],
"type": "waypoint",
"releasedOn": "Feb 17, 2017",
"challengeType": 1,
"translations": {}
},
{
"id": "587d7b89367417b2b2512b4b",
"title": "Use Destructuring Assignment to Assign Variables from Arrays",
"description": [
"ES6 makes destructuring arrays as easy as destructuring objects.",
"One key difference between the spread operator and array destructuring is that the spread operator unpacks all contents of an array into a comma-separated list. Consequently, you cannot pick or choose which elements you want to assign to variables.",
"Destructuring an array lets us do exactly that:",
"<blockquote>const [a, b] = [1, 2, 3, 4, 5, 6];<br>console.log(a, b); // 1, 2</blockquote>",
"The variable <code>a</code> is assigned the first value of the array, and <code>b</code> is assigned the second value of the array.",
"We can also access the value at any index in an array with destructuring by using commas to reach the desired index:",
"<blockquote>const [a, b,,, c] = [1, 2, 3, 4, 5, 6];<br>console.log(a, b, c); // 1, 2, 5 </blockquote>",
"<hr>",
"Use destructuring assignment to swap the values of <code>a</code> and <code>b</code> so that <code>a</code> receives the value stored in <code>b</code>, and <code>b</code> receives the value stored in <code>a</code>."
],
"challengeSeed": [
"let a = 8, b = 6;",
"// change code below this line",
"",
"// change code above this line",
"console.log(a); // should be 6",
"console.log(b); // should be 8"
],
"tests": [
"assert(a === 6, 'message: Value of <code>a</code> should be 6, after swapping.');",
"assert(b === 8, 'message: Value of <code>b</code> should be 8, after swapping.');",
"// assert(/\\[\\s*(\\w)\\s*,\\s*(\\w)\\s*\\]\\s*=\\s*\\[\\s*\\2\\s*,\\s*\\1\\s*\\]/g.test(code), 'message: Use array destructuring to swap a and b.');"
],
"type": "waypoint",
"releasedOn": "Feb 17, 2017",
"challengeType": 1,
"translations": {}
},
{
"id": "587d7b8a367417b2b2512b4c",
"title": "Use Destructuring Assignment with the Rest Operator to Reassign Array Elements",
"description": [
"In some situations involving array destructuring, we might want to collect the rest of the elements into a separate array.",
"The result is similar to <code>Array.prototype.slice()</code>, as shown below:",
"<blockquote>const [a, b, ...arr] = [1, 2, 3, 4, 5, 7];<br>console.log(a, b); // 1, 2<br>console.log(arr); // [3, 4, 5, 7]</blockquote>",
"Variables <code>a</code> and <code>b</code> take the first and second values from the array. After that, because of rest operator's presence, <code>arr</code> gets rest of the values in the form of an array.",
"The rest element only works correctly as the last variable in the list. As in, you cannot use the rest operator to catch a subarray that leaves out last element of the original array.",
"<hr>",
"Use destructuring assignment with the rest operator to perform an effective <code>Array.prototype.slice()</code> so that <code>arr</code> is a sub-array of the original array <code>source</code> with the first two elements ommitted."
],
"challengeSeed": [
"const source = [1,2,3,4,5,6,7,8,9,10];",
"// change code below this line",
"const arr = source; // change this",
"// change code below this line",
"console.log(arr); // should be [3,4,5,6,7,8,9,10]",
"console.log(source); // should be [1,2,3,4,5,6,7,8,9,10];"
],
"tests": [
"// Test arr is [3,4,5,6,7,8,9,10];",
"// Test source is [1,2,3,4,5,6,7,8,9,10];",
"// Test destructuring was used",
"// Test slice was not used"
],
"type": "waypoint",
"releasedOn": "Feb 17, 2017",
"challengeType": 1,
"translations": {}
},
{
"id": "587d7b8a367417b2b2512b4d",
"title": "Use Destructuring Assignment to Pass an Object as a Function's Parameters",
"description": [
"In some cases, you can destructure the object in a function argument itself.",
"Consider the code below:",
"<blockquote>const profileUpdate = (profileData) => {<br> const { name, age, nationality, location } = profileData;<br> // do something with these variables<br>}</blockquote>",
"This effectively destructures the object sent into the function. This can also be done in-place:",
"<blockquote>const profileUpdate = ({ name, age, nationality, location }) => {<br> /* do something with these fields */<br>}</blockquote>",
"This removes some extra lines and makes our code look neat.",
"This has the added benefit of not having to manipulate an entire object in a function; only the fields that are needed are copied inside the function.",
"<hr>",
"Use destructuring assignment within the argument to the function <code>half</code> to send only <code>max</code> and <code>min</code> inside the function."
],
"challengeSeed": [
"const stats = {",
" max: 56.78,",
" standard_deviation: 4.34,",
" median: 34.54,",
" mode: 23.87,",
" min: -0.75,",
" average: 35.85",
"};",
"// change code below this line",
"const half = (stats) => ((stats.max + stats.min) / 2.0); // use function argument destructurung",
"// change code above this line",
"console.log(stats); // should be object",
"console.log(half(stats)); // should be 28.015"
],
"tests": [
"// Test stats is an object",
"// Test half is 28.015",
"// Test destructuring was used"
],
"type": "waypoint",
"releasedOn": "Feb 17, 2017",
"challengeType": 1,
"translations": {}
},
{
"id": "587d7b8a367417b2b2512b4e",
"title": "Create Strings using Template Literals",
"description": [
"A new feature of ES6 is the <dfn>template literal</dfn>. This is a special type of string that allows you to use string interpolation features to create strings.",
"Consider the code below:",
"<blockquote>const person = {<br> name: \"Zodiac Hasbro\",<br> age: 56<br>};<br><br>// string interpolation<br>const greeting = `Hello, my name is ${person.name}!<br>I am ${person.age} years old.`;<br><br>console.log(greeting); // prints<br>// Hello, my name is Zodiac Hasbro!<br>// I am 56 years old.<br></blockquote>",
"A lot of things happened there.",
"Firstly, the <code>${variable}</code> syntax used above is a place holder. Basically, you won't have to use concatenation with the <code>+</code> operator anymore. To add variables to strings, you just drop the variable in a template string and wrap it with <code>${</code> and <code>}</code>.",
"Secondly, the example uses backticks (<code>`</code>), not quotes (<code>'</code> or <code>\"</code>), to wrap the string. Notice that the string is multi-line.",
"This new way of creating strings gives you more flexibility to create robust strings.",
"<hr>",
"Use template literal syntax with backticks to display each entry of the <code>result</code> object's <code>failure</code> array. Each entry should be wrapped inside an <code>li</code> element with the class attribute <code>text-warning</code>."
],
"challengeSeed": [
"const result = {",
" success: [\"max-length\", \"no-amd\", \"prefer-arrow-functions\"],",
" failure: [\"no-var\", \"var-on-top\", \"linebreak\"],",
" skipped: [\"id-blacklist\", \"no-dup-keys\"]",
"};",
"// change code below this line",
"const resultDisplay = null;",
"// change code above this line",
"console.log(resultDisplay);",
"/**",
" * should look like this",
" * <li class=\"text-warning\">no-var</li>",
" * <li class=\"text-warning\">var-on-top</li>",
" * <li class=\"text-warning\">linebreak</li>",
" **/"
],
"tests": [
"// Test resultDisplay is a string",
"// Test resultDisplay is the desired output",
"// Test template strings were used"
],
"type": "waypoint",
"releasedOn": "Feb 17, 2017",
"challengeType": 1,
"translations": {}
},
{
"id": "587d7b8a367417b2b2512b4f",
"title": "Write Concise Object Literal Declarations Using Simple Fields",
"description": [
"ES6 adds some nice support for easily definining object literals.",
"Consider the following code:",
"<blockquote>const getMousePosition = (x, y) => ({<br> x: x,<br> y: y<br>});</blockquote>",
"<code>getMousePosition</code> is a simple function that returns an object containing two fields.",
"ES6 provides the syntactic sugar to eliminate the redundancy of having to write <code>x: x</code>. You can simply write <code>x</code> once, and it will be converted to<code>x: x</code> (or something equivalent) under the hood.",
"Here is the same function from above rewritten to use this new syntax:",
"<blockquote>const getMousePosition = (x, y) => ({ x, y });</blockquote>",
"<hr>",
"Use simple fields with object literals to create and return a <code>Person</code> object."
],
"challengeSeed": [
"// change code below this line",
"const createPerson = (name, age, gender) => {",
" return {",
" name: name,",
" age: age,",
" gender: gender",
" };",
"};",
"// change code above this line",
"console.log(createPerson(\"Zodiac Hasbro\", 56, \"male\")); // returns a proper object"
],
"tests": [
"// Test the output is {name: \"Zodiac Hasbro\", age: 56, gender: \"male\"}",
"// Test no : was present"
],
"type": "waypoint",
"releasedOn": "Feb 17, 2017",
"challengeType": 1,
"translations": {}
},
{
"id": "587d7b8b367417b2b2512b50",
"title": "Write Concise Declarative Functions with ES6",
"description": [
"When defining functions within objects in ES5, we have to use the keyword <code>function</code> as follows:",
"<blockquote>const person = {<br> name: \"Taylor\",<br> sayHello: function() {<br> return `Hello! My name is ${this.name}.`;<br> }<br>};</blockquote>",
"With ES6, You can remove the <code>function</code> keyword and colon altogether when defining functions in objects. Here's an example of this syntax:",
"<blockquote>const person = {<br> name: \"Taylor\",<br> sayHello() {<br> return `Hello! My name is ${this.name}.`;<br> }<br>};</blockquote>",
"<hr>",
"Refactor the function <code>setGear</code> inside the object <code>bicycle</code> to use the shorthand syntax described above."
],
"challengeSeed": [
"// change code below this line",
"const bicycle = {",
" gear: 2,",
" setGear: function(newGear) {",
" this.gear = newGear;",
" }",
"};",
"// change code above this line",
"bicycle.setGear(3);",
"console.log(bicycle.gear);"
],
"tests": [
"// Test the output is Sending request to Yanoshi Mimoto",
"// Test no : was present"
],
"type": "waypoint",
"releasedOn": "Feb 17, 2017",
"challengeType": 1,
"translations": {}
},
{
"id": "587d7b8b367417b2b2512b53",
"title": "Use class Syntax to Define a Constructor Function",
"description": [
"ES6 provides a new syntax to help create objects, using the keyword <dfn>class</dfn>.",
"This is to be noted, that the <code>class</code> syntax is just a syntax, and not a full-fledged class based implementation of object oriented paradigm, unlike in languages like Java, or Python, or Ruby etc.",
"In ES5, we usually define a constructor function, and use the <code>new</code> keyword to instantiate an object.",
"<blockquote>var SpaceShuttle = function(targetPlanet){<br> this.targetPlanet = targetPlanet;<br>}<br>var zeus = new spaceShuttle('Jupiter');</blockquote>",
"The class syntax simply replaces the constructor function creation:",
"<blockquote>class SpaceShuttle {<br> constructor(targetPlanet){<br> this.targetPlanet = targetPlanet;<br> }<br>}<br>const zeus = new spaceShuttle('Jupiter');</blockquote>",
"Notice that the <code>class</code> keyword declares a new function, and a constructor was added, which would be invoked when <code>new</code> is called - to create a new object.",
"<hr>",
"Use <code>class</code> keyword and write a proper constructor to create the <code>Vegetable</code> class.",
"The <code>Vegetable</code> lets you create a vegetable object, with a property <code>name</code>, to be passed to constructor."
],
"challengeSeed": [
"/* Alter code below this line */",
"const Vegetable = undefined;",
"/* Alter code above this line */",
"const carrot = new Vegetable('carrot');",
"console.log(carrot.name); // => should be 'carrot'"
],
"tests": [
"// Test the Vegetable is a class",
"// Test that class keyword was used",
"// Test that other objects could be created with the class"
],
"type": "waypoint",
"releasedOn": "Feb 17, 2017",
"challengeType": 1,
"translations": {}
},
{
"id": "587d7b8c367417b2b2512b54",
"title": "Use getters and setters to Control Access to an Object",
"description": [
"You can obtain values from an object, and set a value of a property within an object.",
"These are classically called <dfn>getters</dfn> and <dfn>setters</dfn>.",
"Getter functions are meant to simply return (get) the value of an object's private variable to the user without the user directly accessing the private variable.",
"Setter functions are meant to modify (set) the value of an object's private variable based on the value passed into the setter function. This change could involve calculations, or even overwriting the previous value completely.",
"<blockquote>class Book {<br> constructor(author) {<br> this._author = author;<br> }<br> // getter<br> get writer(){<br> return this._author;<br> }<br> // setter<br> set writer(updatedAuthor){<br> this._author = updatedAuthor;<br> }<br>}<br>const lol = new Book('anonymous');<br>console.log(lol.writer);<br>lol.writer = 'wut';<br>console.log(lol.writer);</blockquote>",
"Notice the syntax we are using to invoke the getter and setter - as if they are not even functions.",
"Getters and setters are important, because they hide internal implementation details.",
"<hr>",
"Use <code>class</code> keyword to create a Thermostat class. The constructor accepts Farenheit temperature.",
"Now create <code>getter</code> and <code>setter</code> in the class, to obtain the temperature in Celsius scale.",
"Remember that <code>F = C * 9.0 / 5 + 32</code>, where F is the value of temperature in Fahrenheit scale, and C is the value of the same temperature in Celsius scale",
"Note",
"When you implement this, you would be tracking the temperature inside the class in one scale - either Fahrenheit or Celsius.",
"This is the power of getter or setter - you are creating an API for another user, who would get the correct result, no matter which one you track.",
"In other words, you are abstracting implementation details from the consumer."
],
"challengeSeed": [
"/* Alter code below this line */",
"const Thermostat = undefined;",
"/* Alter code above this line */",
"const thermos = new Thermostat(76); // setting in Farenheit scale",
"let temp = thermos.temperature; // 24.44 in C",
"thermos.temperature = 26;",
"temp = thermos.temperature; // 26 in C"
],
"tests": [
"// Test the Thermostat is a class",
"// Test that class keyword was used",
"// Test that other objects could be created with the class"
],
"type": "waypoint",
"releasedOn": "Feb 17, 2017",
"challengeType": 1,
"translations": {}
},
{
"id": "587d7b8c367417b2b2512b55",
"title": "Understand the Differences Between import and require",
"description": [
"In the past, the function <code>require()</code> would be used to import the functions and code in external files and modules. While handy, this presents a problem: some files and modules are rather large, and you may only need certain code from those external resources.",
"ES6 gives us a very handy tool known as <dfn>import</dfn>. With it, we can choose which parts of a module or file to load into a given file, saving time and memory.",
"Consider the following example. Imagine that <code>math_array_functions</code> has about 20 functions, but I only need one, <code>countItems</code>, in my current file. The old <code>require()</code> approach would force me to bring in all 20 functions. With this new <code>import</code> syntax, I can bring in just the desired function, like so:",
"<blockquote>import { countItems } from \"math_array_functions\"</blockquote>",
"A description of the above code:",
"<blockquote>import { function } from \"file_path_goes_here\"<br>// We can also import variables the same way!</blockquote>",
"There are a few ways to write an <code>import</code> statement, but the above is a very common use-case.",
"<strong>Note</strong><br>the whitespace surrounding the function inside the curly braces is a best practice - it makes it easier to read the <code>import</code> statement.",
"<strong>Note</strong><br>The lessons in this section handle non-browser features. <code>import</code>, and the statements we introduce in the rest of these lessons, won't work on a browser directly, However, we can use various tools to create code out of this to make it work in browser.",
"<hr>",
"Add the appropriate <code>import</code> statement that will allow the current file to use the <code>capitalizeString</code> function. The file where this function lives is called <code>\"string_functions\"</code>, and it is in the same directory as the current file."
],
"challengeSeed": [
"capitalizeString(\"hello!\");"
],
"tests": [
"assert(code.match(/import\\s+\\{\\s?capitalizeString\\s?\\}\\s+from\\s+\"string_functions\"/ig)"
],
"type": "waypoint",
"releasedOn": "Feb 17, 2017",
"challengeType": 1,
"translations": {}
},
{
"id": "587d7b8c367417b2b2512b56",
"title": "Use export to Reuse a Code Block",
"description": [
"In the previous challenge, you learned about <code>import</code> and how it can be leveraged to import small amounts of code from large files. In order for this to work, though, we must utilize one of the statements that goes with <code>import</code>, known as <dfn>export</dfn>. When we want some code - a function, or a variable - to be usable in another file, we must export it in order to import it into another file. Like <code>import</code>, <code>export</code> is a non-browser feature.",
"The following is what we refer to as a <dfn>named export</dfn>. With this, we can import any code we export into another file with the <code>import</code> syntax you learned in the last lesson. Here's an example:",
"<blockquote>const capitalizeString = (string) => {<br> return string.charAt(0).toUpperCase() + string.slice(1);<br>}<br>export { capitalizeString } //How to export functions.<br>export const foo = \"bar\"; //How to export variables.</blockquote>",
"Alternatively, if you would like to compact all your <code>export</code> statements into one line, you can take this approach:",
"<blockquote>const capitalizeString = (string) => {<br> return string.charAt(0).toUpperCase() + string.slice(1);<br>}<br>const foo = \"bar\";<br>export { capitalizeString, foo }</blockquote>",
"Either approach is perfectly acceptable.",
"<hr>",
"Below are two variables that I want to make available for other files to use. Utilizing the first way I demonstrated <code>export</code>, export the two variables."
],
"challengeSeed": [
"const foo = \"bar\";",
"const boo = \"far\";"
],
"tests": [
"assert(code.match(/export\\s+const\\s+foo\\s+=+\\s\"bar\"/ig))",
"assert(code.match(/export\\s+const\\s+boo\\s+=+\\s\"far\"/ig))"
],
"type": "waypoint",
"releasedOn": "Feb 17, 2017",
"challengeType": 1,
"translations": {}
},
{
"id": "587d7b8c367417b2b2512b57",
"title": "Use * to Import Everything from a File",
"description": [
"Suppose you have a file that you wish to import all of its contents into the current file. This can be done with the <dfn>import *</dfn> syntax.",
"Here's an example where the contents of a file named <code>\"math_functions\"</code> are imported into a file in the same directory:",
"<blockquote>import * as myMathModule from \"math_functions\"<br>myMathModule.add(2,3);<br>myMathModule.subtract(5,3);</blockquote>",
"And breaking down that code:",
"<blockquote>import * as object_with_name_of_your_choice from \"file_path_goes_here\"<br>object_with_name_of_your_choice.imported_function</blockquote>",
"You may use any name following the <code>import *</code> as portion of the statement. In order to utilize this method, it requires an object that receives the imported values. From here, you will use the dot notation to call your imported values.",
"<hr>",
"The code below requires the contents of a file, <code>\"capitalize_strings\"</code>, found in the same directory as it, imported. Add the appropriate <code>import *</code> statement to the top of the file, using the object provided."
],
"challengeSeed": [
"myStringModule.capitalize(\"foo\");",
"myStringModule.lowercase(\"Foo\");"
],
"tests": [
"assert(code.match(/import\\s+\\*\\s+as\\s+myStringModule\\s+from\\s+\"capitalize_strings\"/ig))"
],
"type": "waypoint",
"releasedOn": "Feb 17, 2017",
"challengeType": 1,
"translations": {}
},
{
"id": "587d7b8c367417b2b2512b58",
"title": "Create an Export Fallback with export default",
"description": [
"In the <code>export</code> lesson, you learned about the syntax referred to as a <dfn>named export</dfn>. This allowed you to make multiple functions and variables available for use in other files.",
"There is another <code>export</code> syntax you need to know, known as <dfn>export default</dfn>. Usually you will use this syntax if only one value is being exported from a file. It is also used to create a fallback value for a file or module.",
"Here is a quick example of <code>export default</code>:",
"<blockquote>export default const add = (x,y) => {<br> return x + y;<br>}</blockquote>",
"There is a one major feature of <code>export default</code> you must never forget - since it is used to declare a fallback value for a module or file, you can only have one value be a default export in each module or file.",
"<hr>",
"The following function should be the fallback value for the module. Please add the necessary code to do so."
],
"challengeSeed": [
"const subtract = (x,y) => {return x - y;}"
],
"tests": [
"assert(code.match(/export\\s+default\\s+const\\s+subtract\\s+=\\s+\\(x,y\\)\\s+=>\\s+{return\\s+x\\s-\\s+y;}/ig))"
],
"type": "waypoint",
"releasedOn": "Feb 17, 2017",
"challengeType": 1,
"translations": {}
},
{
"id": "587d7b8d367417b2b2512b59",
"title": "Import a Default Export",
"description": [
"In the last challenge, you learned about <code>export default</code> and its uses. It is important to note that, to import a default export, you need to use a different <code>import</code> syntax.",
"In the following example, we have a function, <code>add</code>, that is the default export of a file, <code>\"math_functions\"</code>. Here is how to import it:",
"<blockquote>import add from \"math_functions\";<br>add(5,4); //Will return 9</blockquote>",
"The syntax differs in one key place - the imported value, <code>add</code>, is not surrounded by curly braces, <code>{}</code>. Unlike exported values, the primary method of importing a default export is to simply write the value's name after <code>import</code>.",
"<hr>",
"In the following code, please import the default export, <code>subtract</code>, from the file <code>\"math_functions\"</code>, found in the same directory as this file."
],
"challengeSeed": [
"subtract(7,4);"
],
"tests": [
"assert(code.match(/import\\s+subtract\\s+from\\s+\"math_functions\"/ig))"
],
"type": "waypoint",
"releasedOn": "Feb 17, 2017",
"challengeType": 1,
"translations": {}
}
]
}

View File

@@ -0,0 +1,998 @@
{
"name": "Regular Expressions",
"order": 3,
"time": "5 hours",
"helpRoom": "Help",
"challenges": [
{
"id": "587d7db3367417b2b2512b8d",
"title": "Introduction to the Regular Expression Challenges",
"description": [
[
"https://camo.githubusercontent.com/85ac1a6783961ce77add6b2e8630dbf6521d33b2/687474703a2f2f696d67732e786b63642e636f6d2f636f6d6963732f726567756c61725f65787072657373696f6e732e706e67",
"XKCD web comic showing how regular expressions can save the day",
"Regular expressions are special strings that represent a search pattern. Also known as \"regex\" or \"regexp\", they help programmers match, search, and replace text. Regular expressions can appear cryptic because a few characters have special meaning. The goal is to combine the symbols and text into a pattern that matches what you want, but only what you want. This section will cover the characters, a few shortcuts, and the common uses for writing regular expressions.",
""
]
],
"releasedOn": "Feb 17, 2017",
"challengeSeed": [],
"tests": [],
"type": "waypoint",
"challengeType": 7,
"isRequired": false,
"translations": {}
},
{
"id": "587d7db3367417b2b2512b8e",
"title": "Using the Test Method",
"description": [
"Regular expressions are used in programming languages to match parts of strings. You create patterns to help you do that matching.",
"If you want to find the word <code>\"the\"</code> in the string <code>\"The dog chased the cat\"</code>, you could use the following regular expression: <code>/the/</code>. Notice that quote marks are not required within the regular expression.",
"JavaScript has multiple ways to use regexes. One way to test a regex is using the <code>.test()</code> method. The <code>.test()</code> method takes the regex, applies it to a string (which is placed inside the parentheses), and returns <code>true</code> or <code>false</code> if your pattern finds something or not.",
"<blockquote>let testStr = \"freeCodeCamp\";<br>let testRegex = /Code/;<br>testRegex.test(testStr);<br>// Returns true</blockquote>",
"<hr>",
"Apply the regex <code>myRegex</code> on the string <code>myString</code> using the <code>.test()</code> method."
],
"challengeSeed": [
"let myString = \"Hello, World!\";",
"let myRegex = /Hello/;",
"let result = myRegex; // Change this line"
],
"tests": [
"assert(code.match(/myRegex.test\\(\\s*myString\\s*\\)/), 'message: You should use <code>.test()</code> to test the regex.');",
"assert(result === true, 'message: Your result should return <code>true</code>.');"
],
"solutions": [],
"hints": [],
"type": "waypoint",
"releasedOn": "Feb 17, 2017",
"challengeType": 1,
"translations": {}
},
{
"id": "587d7db3367417b2b2512b8f",
"title": "Match Literal Strings",
"description": [
"In the last challenge, you searched for the word <code>\"Hello\"</code> using the regular expression <code>/Hello/</code>. That regex searched for a literal match of the string <code>\"Hello\"</code>. Here's another example searching for a literal match of the string <code>\"Kevin\"</code>:",
"<blockquote>let testStr = \"Hello, my name is Kevin.\";<br>let testRegex = /Kevin/;<br>testRegex.test(testStr);<br>// Returns true</blockquote>",
"Any other forms of <code>\"Kevin\"</code> will not match. For example, the regex <code>/Kevin/</code> will not match <code>\"kevin\"</code> or <code>\"KEVIN\"</code>.",
"<blockquote>let wrongRegex = /kevin/;<br>wrongRegex.test(testStr);<br>// Returns false</blockquote>",
"A future challenge will show how to match those other forms as well.",
"<hr>",
"Complete the regex <code>waldoRegex</code> to find <code>\"Waldo\"</code> in the string <code>waldoIsHiding</code> with a literal match."
],
"challengeSeed": [
"let waldoIsHiding = \"Somewhere Waldo is hiding in this text.\";",
"let waldoRegex = /search/; // Change this line",
"let result = waldoRegex.test(waldoIsHiding);"
],
"tests": [
"assert(waldoRegex.test(waldoIsHiding), 'message: Your regex <code>waldoRegex</code> should find <code>\"Waldo\"</code>');",
"assert(!waldoRegex.test('Somewhere is hiding in this text.'), 'message: Your regex <code>waldoRegex</code> should not search for anything else.');",
"assert(!/\\/.*\\/i/.test(code), 'message: You should perform a literal string match with your regex.');"
],
"solutions": [],
"hints": [],
"type": "waypoint",
"releasedOn": "Feb 17, 2017",
"challengeType": 1,
"translations": {}
},
{
"id": "587d7db4367417b2b2512b90",
"title": "Match a Literal String with Different Possibilities",
"description": [
"Using regexes like <code>/coding/</code>, you can look for the pattern <code>\"coding\"</code> in another string.",
"This is powerful to search single strings, but it's limited to only one pattern. You can search for multiple patterns using the <code>alternation</code> or <code>OR</code> operator: <code>|</code>.",
"This operator matches patterns either before or after it. For example, if you wanted to match <code>\"yes\"</code> or <code>\"no\"</code>, the regex you want is <code>/yes|no/</code>.",
"You can also search for more than just two patterns. You can do this by adding more patterns with more <code>OR</code> operators separating them, like <code>/yes|no|maybe/</code>.",
"<hr>",
"Complete the regex <code>petRegex</code> to match the pets <code>\"dog\"</code>, <code>\"cat\"</code>, <code>\"bird\"</code>, or <code>\"fish\"</code>."
],
"challengeSeed": [
"let petString = \"James has a pet cat.\";",
"let petRegex = /change/; // Change this line",
"let result = petRegex.test(petString);"
],
"tests": [
"assert(petRegex.test('John has a pet dog.'), 'message: Your regex <code>petRegex</code> should return <code>true</code> for the string <code>\"John has a pet dog.\"</code>');",
"assert(!petRegex.test('Emma has a pet rock.'), 'message: Your regex <code>petRegex</code> should return <code>false</code> for the string <code>\"Emma has a pet rock.\"</code>');",
"assert(petRegex.test('Emma has a pet bird.'), 'message: Your regex <code>petRegex</code> should return <code>true</code> for the string <code>\"Emma has a pet bird.\"</code>');",
"assert(petRegex.test('Liz has a pet cat.'), 'message: Your regex <code>petRegex</code> should return <code>true</code> for the string <code>\"Liz has a pet cat.\"</code>');",
"assert(!petRegex.test('Kara has a pet dolphin.'), 'message: Your regex <code>petRegex</code> should return <code>false</code> for the string <code>\"Kara has a pet dolphin.\"</code>');",
"assert(petRegex.test('Alice has a pet fish.'), 'message: Your regex <code>petRegex</code> should return <code>true</code> for the string <code>\"Alice has a pet fish.\"</code>');",
"assert(!petRegex.test('Jimmy has a pet computer.'), 'message: Your regex <code>petRegex</code> should return <code>false</code> for the string <code>\"Jimmy has a pet computer.\"</code>');"
],
"solutions": [],
"hints": [],
"type": "waypoint",
"releasedOn": "Feb 17, 2017",
"challengeType": 1,
"translations": {}
},
{
"id": "587d7db4367417b2b2512b91",
"title": "Ignore Case While Matching",
"description": [
"Up until now, you've looked at regexes to do literal matches of strings. But sometimes, you might want to also match case differences.",
"Case (or sometimes letter case) is the difference between uppercase letters and lowercase letters. Examples of uppercase are <code>\"A\"</code>, <code>\"B\"</code>, and <code>\"C\"</code>. Examples of lowercase are <code>\"a\"</code>, <code>\"b\"</code>, and <code>\"c\"</code>.",
"You can match both cases using what is called a flag. There are other flags but here you'll focus on the flag that ignores case - the <code>i</code> flag. You can use it by appending it to the regex. An example of using this flag is <code>/ignorecase/i</code>. This regex can match the strings <code>\"ignorecase\"</code>, <code>\"igNoreCase\"</code>, and <code>\"IgnoreCase\"</code>.",
"<hr>",
"Write a regex <code>fccRegex</code> to match <code>\"freeCodeCamp\"</code>, no matter its case. Your regex should not match any abbreviations or variations with spaces."
],
"challengeSeed": [
"let myString = \"freeCodeCamp\";",
"let fccRegex = /change/; // Change this line",
"let result = fccRegex.test(myString);"
],
"tests": [
"assert(fccRegex.test('freeCodeCamp'), 'message: Your regex should match <code>freeCodeCamp</code>');",
"assert(fccRegex.test('FreeCodeCamp'), 'message: Your regex should match <code>FreeCodeCamp</code>');",
"assert(fccRegex.test('FreecodeCamp'), 'message: Your regex should match <code>FreecodeCamp</code>');",
"assert(fccRegex.test('FreeCodecamp'), 'message: Your regex should match <code>FreeCodecamp</code>');",
"assert(!fccRegex.test('Free Code Camp'), 'message: Your regex should not match <code>Free Code Camp</code>');",
"assert(fccRegex.test('FreeCOdeCamp'), 'message: Your regex should match <code>FreeCOdeCamp</code>');",
"assert(!fccRegex.test('FCC'), 'message: Your regex should not match <code>FCC</code>');",
"assert(fccRegex.test('FrEeCoDeCamp'), 'message: Your regex should match <code>FrEeCoDeCamp</code>');",
"assert(fccRegex.test('FrEeCodECamp'), 'message: Your regex should match <code>FrEeCodECamp</code>');",
"assert(fccRegex.test('FReeCodeCAmp'), 'message: Your regex should match <code>FReeCodeCAmp</code>');"
],
"solutions": [],
"hints": [],
"type": "waypoint",
"releasedOn": "Feb 17, 2017",
"challengeType": 1,
"translations": {}
},
{
"id": "587d7db4367417b2b2512b92",
"title": "Extract Matches",
"description": [
"So far, you have only been checking if a pattern exists or not within a string. You can also extract the actual matches you found with the <code>.match()</code> method.",
"To use the <code>.match()</code> method, apply the method on a string and pass in the regex inside the parentheses. Here's an example:",
"<blockquote>\"Hello, World!\".match(/Hello/);<br>// Returns [\"Hello\"]<br>let ourStr = \"Regular expressions\";<br>let ourRegex = /expressions/;<br>ourStr.match(ourRegex);<br>// Returns [\"expressions\"]</blockquote>",
"<hr>",
"Apply the <code>.match()</code> method to extract the word <code>coding</code>."
],
"challengeSeed": [
"let extractStr = \"Extract the word 'coding' from this string.\";",
"let codingRegex = /change/; // Change this line",
"let result = extractStr; // Change this line"
],
"tests": [
"assert(result.join() === \"coding\", 'message: The <code>result</code> should have the word <code>coding</code>');",
"assert(codingRegex.source === \"coding\", 'message: Your regex <code>codingRegex</code> should search for <code>coding</code>');",
"assert(code.match(/\\.match\\(.*\\)/), 'message: You should use the <code>.match()</code> method.');"
],
"solutions": [],
"hints": [],
"type": "waypoint",
"releasedOn": "Feb 17, 2017",
"challengeType": 1,
"translations": {}
},
{
"id": "587d7db4367417b2b2512b93",
"title": "Find More Than the First Match",
"description": [
"So far, you have only been able to extract or search a pattern once.",
"<blockquote>let testStr = \"Repeat, Repeat, Repeat\";<br>let ourRegex = /Repeat/;<br>testStr.match(ourRegex);<br>// Returns [\"Repeat\"]</blockquote>",
"To search or extract a pattern more than once, you can use the <code>g</code> flag.",
"<blockquote>let repeatRegex = /Repeat/g;<br>testStr.match(repeatRegex);<br>// Returns [\"Repeat\", \"Repeat\", \"Repeat\"]</blockquote>",
"<hr>",
"Using the regex <code>starRegex</code>, find and extract both <code>\"Twinkle\"</code> words from the string <code>twinkleStar</code>.",
"<strong>Note</strong><br>You can have multiple flags on your regex like <code>/search/gi</code>"
],
"challengeSeed": [
"let twinkleStar = \"Twinkle, twinkle, little star\";",
"let starRegex = /change/; // Change this line",
"let result = twinkleStar; // Change this line"
],
"tests": [
"assert(starRegex.flags.match(/g/).length == 1, 'message: Your regex <code>starRegex</code> should use the global flag <code>g</code>');",
"assert(starRegex.flags.match(/i/).length == 1, 'message: Your regex <code>starRegex</code> should use the case insensitive flag <code>i</code>');",
"assert(result.sort().join() == twinkleStar.match(/twinkle/gi).sort().join(), 'message: Your match should match both occurrences of the word <code>\"Twinkle\"</code>');",
"assert(result.length == 2, 'message: Your match <code>result</code> should have two elements in it.');"
],
"solutions": [],
"hints": [],
"type": "waypoint",
"releasedOn": "Feb 17, 2017",
"challengeType": 1,
"translations": {}
},
{
"id": "587d7db5367417b2b2512b94",
"title": "Match Anything with Wildcard Period",
"description": [
"Sometimes you won't (or don't need to) know the exact characters in your patterns. Thinking of all words that match, say, a misspelling would take a long time. Luckily, you can save time using the wildcard character: <code>.</code>",
"The wildcard character <code>.</code> will match any one character. The wildcard is also called <code>dot</code> and <code>period</code>. You can use the wildcard character just like any other character in the regex. For example, if you wanted to match <code>\"hug\"</code>, <code>\"huh\"</code>, <code>\"hut\"</code>, and <code>\"hum\"</code>, you can use the regex <code>/hu./</code> to match all four words.",
"<blockquote>let humStr = \"I'll hum a song\";<br>let hugStr = \"Bear hug\";<br>let huRegex = /hu./;<br>humStr.match(huRegex); // Returns [\"hum\"]<br>hugStr.match(huRegex); // Returns [\"hug\"]</blockquote>",
"<hr>",
"Complete the regex <code>unRegex</code> so that it matches the strings <code>\"run\"</code>, <code>\"sun\"</code>, <code>\"fun\"</code>, <code>\"pun\"</code>, <code>\"nun\"</code>, and <code>\"bun\"</code>. Your regex should use the wildcard character."
],
"challengeSeed": [
"let exampleStr = \"Let's have fun with regular expressions!\";",
"let unRegex = /change/; // Change this line",
"let result = unRegex.test(exampleStr);"
],
"tests": [
"assert(code.match(/\\.test\\(.*\\)/), 'message: You should use the <code>.test()</code> method.');",
"assert(/\\./.test(unRegex.source), 'message: You should use the wildcard character in your regex <code>unRegex</code>');",
"assert(unRegex.test(\"Let us go on a run.\"), 'message: Your regex <code>unRegex</code> should match <code>\"run\"</code> in <code>\"Let us go on a run.\"</code>');",
"assert(unRegex.test(\"The sun is out today.\"), 'message: Your regex <code>unRegex</code> should match <code>\"sun\"</code> in <code>\"The sun is out today.\"</code>');",
"assert(unRegex.test(\"Coding is a lot of fun.\"), 'message: Your regex <code>unRegex</code> should match <code>\"fun\"</code> in <code>\"Coding is a lot of fun.\"</code>');",
"assert(unRegex.test(\"Seven days without a pun makes one weak.\"), 'message: Your regex <code>unRegex</code> should match <code>\"pun\"</code> in <code>\"Seven days without a pun makes one weak.\"</code>');",
"assert(unRegex.test(\"One takes a vow to be a nun.\"), 'message: Your regex <code>unRegex</code> should match <code>\"nun\"</code> in <code>\"One takes a vow to be a nun.\"</code>');",
"assert(unRegex.test(\"She got fired from the hot dog stand for putting her hair in a bun.\"), 'message: Your regex <code>unRegex</code> should match <code>\"bun\"</code> in <code>\"She got fired from the hot dog stand for putting her hair in a bun.\"</code>');",
"assert(!unRegex.test(\"There is a bug in my code.\"), 'message: Your regex <code>unRegex</code> should not match <code>\"There is a bug in my code.\"</code>');",
"assert(!unRegex.test(\"Can me if you can.\"), 'message: Your regex <code>unRegex</code> should not match <code>\"Catch me if you can.\"</code>');"
],
"solutions": [],
"hints": [],
"type": "waypoint",
"releasedOn": "Feb 17, 2017",
"challengeType": 1,
"translations": {}
},
{
"id": "587d7db5367417b2b2512b95",
"title": "Match Single Character with Multiple Possibilities",
"description": [
"You learned how to match literal patterns (<code>/literal/</code>) and wildcard character (<code>/./</code>). Those are the extremes of regular expressions, where one finds exact matches and the other matches everything. There are options that are a balance between the two extremes.",
"You can search for a literal pattern with some flexibility with <code>character classes</code>. Character classes allow you to define a group of characters you wish to match by placing them inside square (<code>[</code> and <code>]</code>) brackets.",
"For example, you want to match <code>\"bag\"</code>, <code>\"big\"</code>, and <code>\"bug\"</code> but not <code>\"bog\"</code>. You can create the regex <code>/b[aiu]g/</code> to do this. The <code>[aiu]</code> is the character class that will only match the characters <code>\"a\"</code>, <code>\"i\"</code>, or <code>\"u\"</code>.",
"<blockquote>let bigStr = \"big\";<br>let bagStr = \"bag\";<br>let bugStr = \"bug\";<br>let bogStr = \"bog\";<br>let bgRegex = /b[aiu]g/;<br>bigStr.match(bgRegex); // Returns [\"big\"]<br>bagStr.match(bgRegex); // Returns [\"bag\"]<br>bugStr.match(bgRegex); // Returns [\"bug\"]<br>bogStr.match(bgRegex); // Returns null</blockquote>",
"<hr>",
"Use a character class with vowels (<code>a</code>, <code>e</code>, <code>i</code>, <code>o</code>, <code>u</code>) in your regex <code>vowelRegex</code> to find all the vowels in the string <code>quoteSample</code>.",
"<strong>Note</strong><br>Be sure to match both upper- and lowercase vowels."
],
"challengeSeed": [
"let quoteSample = \"Beware of bugs in the above code; I have only proved it correct, not tried it.\";",
"let vowelRegex = /change/; // Change this line",
"let result = vowelRegex; // Change this line"
],
"tests": [
"assert(result.length == 25, 'message: You should find all 25 vowels.');",
"assert(/\\[.*\\]/.test(vowelRegex.source), 'message: Your regex <code>vowelRegex</code> should use a character class.');",
"assert(vowelRegex.flags.match(/g/).length == 1, 'message: Your regex <code>vowelRegex</code> should use the global flag.');",
"assert(vowelRegex.flags.match(/i/).length == 1, 'message: Your regex <code>vowelRegex</code> should use the case insensitive flag.');",
"assert(!/[b-df-hj-np-tv-z]/gi.test(result.join()), 'message: Your regex should not match any consonants.');"
],
"solutions": [],
"hints": [],
"type": "waypoint",
"releasedOn": "Feb 17, 2017",
"challengeType": 1,
"translations": {}
},
{
"id": "587d7db5367417b2b2512b96",
"title": "Match Letters of the Alphabet",
"description": [
"You saw how you can use <code>character sets</code> to specify a group of characters to match, but that's a lot of typing when you need to match a large range of characters (for example, every letter in the alphabet). Fortunately, there is a built-in feature that makes this short and simple.",
"Inside a <code>character set</code>, you can define a range of characters to match using a <code>hyphen</code> character: <code>-</code>.",
"For example, to match lowercase letters <code>a</code> through <code>e</code> you would use <code>[a-e]</code>.",
"<blockquote>let catStr = \"cat\";<br>let batStr = \"bat\";<br>let matStr = \"mat\";<br>let bgRegex = /[a-e]at/;<br>catStr.match(bgRegex); // Returns [\"cat\"]<br>batStr.match(bgRegex); // Returns [\"bat\"]<br>matStr.match(bgRegex); // Returns null</blockquote>",
"<hr>",
"Match all the letters in the string <code>quoteSample</code>.",
"<strong>Note</strong><br>Be sure to match both upper- and lowercase vowels."
],
"challengeSeed": [
"let quoteSample = \"The quick brown fox jumps over the lazy dog.\";",
"let alphabetRegex = /change/; // Change this line",
"let result = alphabetRegex; // Change this line"
],
"tests": [
"assert(result.length == 35, 'message: Your regex <code>alphabetRegex</code> should match 35 items.');",
"assert(alphabetRegex.flags.match(/g/).length == 1, 'message: Your regex <code>alphabetRegex</code> should use the global flag.');",
"assert(alphabetRegex.flags.match(/i/).length == 1, 'message: Your regex <code>alphabetRegex</code> should use the case insensitive flag.');"
],
"solutions": [],
"hints": [],
"type": "waypoint",
"releasedOn": "Feb 17, 2017",
"challengeType": 1,
"translations": {}
},
{
"id": "587d7db5367417b2b2512b97",
"title": "Match Numbers and Letters of the Alphabet",
"description": [
"Using the hyphen (<code>-</code>) to match a range of characters is not limited to letters. It also works to match a range of numbers.",
"For example, <code>/[0-5]/</code> matches any number between <code>0</code> and <code>5</code>, including the <code>0</code> and <code>5</code>.",
"Also, it is possible to combine a range of letters and numbers in a single character set.",
"<blockquote>let jennyStr = \"Jenny8675309\";<br>let myRegex = /[a-z0-9]/ig;<br>// matches all letters and numbers in jennyStr<br>jennyStr.match(myRegex);</blockquote>",
"<hr>",
"Create a single regex that matches a range of letters between <code>h</code> and <code>s</code>, and a range of numbers between <code>2</code> and <code>6</code>. Remember to include the appropriate flags in the regex."
],
"challengeSeed": [
"let quoteSample = \"Blueberry 3.141592653s are delicious.\";",
"let myRegex = /change/; // Change this line",
"let result = myRegex; // Change this line"
],
"tests": [
"assert(result.length == 17, 'message: Your regex <code>myRegex</code> should match 17 items.');",
"assert(myRegex.flags.match(/g/).length == 1, 'message: Your regex <code>myRegex</code> should use the global flag.');",
"assert(myRegex.flags.match(/i/).length == 1, 'message: Your regex <code>myRegex</code> should use the case insensitive flag.');"
],
"solutions": [],
"hints": [],
"type": "waypoint",
"releasedOn": "Feb 17, 2017",
"challengeType": 1,
"translations": {}
},
{
"id": "587d7db6367417b2b2512b98",
"title": "Match Single Characters Not Specified",
"description": [
"So far, you have created a set of characters that you want to match, but you could also create a set of characters that you do not want to match. These types of character sets are called <code>negated character sets</code>.",
"To create a <code>negated character set</code>, you place a <code>caret</code> character (<code>^</code>) after the opening bracket and before the characters you do not want to match.",
"For example, <code>/[^aeiou]/gi</code> matches all characters that are not a vowel. Note that characters like <code>.</code>, <code>!</code>, <code>[</code>, <code>@</code>, <code>/</code> and white space are matched - the negated vowel character set only excludes the vowel characters.",
"<hr>",
"Create a single regex that matches all characters that are not a number or a vowel. Remember to include the appropriate flags in the regex."
],
"challengeSeed": [
"let quoteSample = \"3 blind mice.\";",
"let myRegex = /change/; // Change this line",
"let result = myRegex; // Change this line"
],
"tests": [
"assert(result.length == 9, 'message: Your regex <code>myRegex</code> should match 9 items.');",
"assert(myRegex.flags.match(/g/).length == 1, 'message: Your regex <code>myRegex</code> should use the global flag.');",
"assert(myRegex.flags.match(/i/).length == 1, 'message: Your regex <code>myRegex</code> should use the case insensitive flag.');"
],
"solutions": [],
"hints": [],
"type": "waypoint",
"releasedOn": "Feb 17, 2017",
"challengeType": 1,
"translations": {}
},
{
"id": "587d7db6367417b2b2512b99",
"title": "Match Characters that Occur One or More Times",
"description": [
"Sometimes, you need to match a character (or group of characters) that appears one or more times in a row. This means it occurs at least once, and may be repeated.",
"You can use the <code>+</code> character to check if that is the case. Remember, the character or pattern has to be present consecutively. That is, the character has to repeat one after the other.",
"For example, <code>/a+/g</code> would find one match in <code>\"abc\"</code> and return <code>[\"a\"]</code>. Because of the <code>+</code>, it would also find a single match in <code>\"aabc\"</code> and return <code>[\"aa\"]</code>.",
"If it were instead checking the string <code>\"abab\"</code>, it would find two matches and return <code>[\"a\", \"a\"]</code> because the <code>a</code> characters are not in a row - there is a <code>b</code> between them. Finally, since there is no <code>\"a\"</code> in the string <code>\"bcd\"</code>, it wouldn't find a match.",
"<hr>",
"You want to find matches when the letter <code>s</code> occurs one or more times in <code>\"Mississippi\"</code>. Write a regex that uses the <code>+</code> sign."
],
"challengeSeed": [
"let difficultSpelling = \"Mississippi\";",
"let myRegex = /change/; // Change this line",
"let result = difficultSpelling.match(myRegex);"
],
"tests": [
"assert(/\\+/.test(myRegex.source), 'message: Your regex <code>myRegex</code> should use the <code>+</code> sign to match one or more <code>s</code> characters.');",
"assert(result.length == 2, 'message: Your regex <code>myRegex</code> should match 2 items.');",
"assert(result[0] == 'ss' && result[1] == 'ss', 'message: The <code>result</code> variable should be an array with two matches of <code>\"ss\"</code>');"
],
"solutions": [],
"hints": [],
"type": "waypoint",
"releasedOn": "Feb 17, 2017",
"challengeType": 1,
"translations": {}
},
{
"id": "587d7db6367417b2b2512b9a",
"title": "Match Characters that Occur Zero or More Times",
"description": [
"The last challenge used the plus <code>+</code> sign to look for characters that occur one or more times. There's also an option that matches characters that occur zero or more times.",
"The character to do this is the <code>asterisk</code> or <code>star</code>: <code>*</code>.",
"<blockquote>let sWord1 = \"seed\";<br>let sWord2 = \"saw\";<br>let kWord = \"kite\";<br>let sRegex = /s.*/; // Searches for words starting with s<br>sRegex.test(sWord1); // Returns true<br>sRegex.test(sWord2); // Returns true<br>sRegex.test(kWord); // Returns false<br></blockquote>",
"<hr>",
"Create a regex <code>starWarsRegex</code> that uses the <code>*</code> character to match all the movie titles that start with <code>\"Star Wars\"</code>. Your regex does not need flags."
],
"challengeSeed": [
"let starWars = \"Star Wars\";",
"let starWarsRegex = /change/; // Change this line",
"let result = starWars.match(starWarsRegex);"
],
"tests": [
"assert(starWarsRegex.test(\"Star Wars: The Phantom Menace\"), 'message: Your regex should match <code>\"Star Wars: The Phantom Menace\"</code>.');",
"assert(starWarsRegex.test(\"Star Wars: Attack of the Clones\"), 'message: Your regex should match <code>\"Star Wars: Attack of the Clones\"</code>.');",
"assert(starWarsRegex.test(\"Star Wars: Revenge of the Sith\"), 'message: Your regex should match <code>\"Star Wars: Revenge of the Sith\"</code>.');",
"assert(starWarsRegex.test(\"Star Wars: A New Hope\"), 'message: Your regex should match <code>\"Star Wars: A New Hope\"</code>.');",
"assert(starWarsRegex.test(\"Star Wars: The Empire Strikes Back\"), 'message: Your regex should match <code>\"Star Wars: The Empire Strikes Back\"</code>.');",
"assert(starWarsRegex.test(\"Star Wars: Return of the Jedi\"), 'message: Your regex should match <code>\"Star Wars: Return of the Jedi\"</code>.');",
"assert(starWarsRegex.test(\"Star Wars: The Force Awakens\"), 'message: Your regex should match <code>\"Star Wars: The Force Awakens\"</code>.');",
"assert(!starWarsRegex.test(\"The Clone Wars\"), 'message: Your regex should not match <code>\"The Clone Wars\"</code>');"
],
"solutions": [],
"hints": [],
"type": "waypoint",
"releasedOn": "Feb 17, 2017",
"challengeType": 1,
"translations": {}
},
{
"id": "587d7db6367417b2b2512b9b",
"title": "Find Characters with Lazy Matching",
"description": [
"In regular expressions, a <code>greedy</code> match finds the longest possible part of a string that fits the regex pattern and returns it as a match. The alternative is called a <code>lazy</code> match, which finds the smallest possible part of the string that satisfies the regex pattern.",
"You can apply the regex <code>/t[a-z]*i/</code> to the string <code>\"titanic\"</code>. This regex is basically a pattern that starts with <code>t</code>, ends with <code>i</code>, and has some letters in between.",
"Regular expressions are by default <code>greedy</code>, so the match would return <code>[\"titani\"]</code>. It finds the largest sub-string possible to fit the pattern.",
"However, you can use the <code>?</code> character to change it to <code>lazy</code> matching. <code>\"titanic\"</code> matched against the adjusted regex of <code>/t[a-z]*?i/</code> returns <code>[\"ti\"]</code>.",
"<hr>",
"Fix the regex <code>/&lt;.*&gt;/</code> to return the HTML tag <code>&lt;h1&gt;</code> and not the text <code>\"&lt;h1&gt;Winter is coming&lt;/h1&gt;\"</code>. Remember the wildcard <code>.</code> in a regular expression matches any character."
],
"challengeSeed": [
"let text = \"<h1>Winter is coming</h1>\";",
"let myRegex = /<.*>/; // Change this line",
"let result = text.match(myRegex);"
],
"tests": [
"assert(result[0] == '<h1>', 'message: The <code>result</code> variable should be an array with <code>&lt;h1&gt;</code> in it');"
],
"solutions": [],
"hints": [],
"type": "waypoint",
"releasedOn": "Feb 17, 2017",
"challengeType": 1,
"translations": {}
},
{
"id": "587d7db7367417b2b2512b9c",
"title": "Find One or More Criminals in a Hunt",
"description": [
"Time to pause and test your new regex writing skills. A group of criminals escaped from jail and ran away, but you don't know how many. However, you do know that they stay close together when they are around other people. You are responsible for finding all of the criminals at once.",
"Here's an example to review how to do this:",
"The regex <code>/z+/</code> matches the letter <code>z</code> when it appears one or more times in a row. It would find matches in all of the following strings:",
"<blockquote>\"z\"<br>\"zzzzzz\"<br>\"ABCzzzz\"<br>\"zzzzABC\"<br>\"abczzzzzzzzzzzzzzzzzzzzzabc\"</blockquote>",
"But it does not find matches in the following strings since there are no letter <code>z</code> characters:",
"<blockquote>\"\"<br>\"ABC\"<br>\"abcabc\"</blockquote>",
"<hr>",
"Write a <code>greedy</code> regex that finds one or more criminals within a group of other people. A criminal is represented by the capital letter <code>C</code>."
],
"challengeSeed": [
"// example crowd gathering",
"let crowd = 'P1P2P3P4P5P6CCCP7P8P9';",
"",
"let reCriminals = /./; // Change this line",
"",
"let matchedCriminals = crowd.match(reCriminals);",
"console.log(matchedCriminals);"
],
"tests": [
"assert('C'.match(reCriminals) && 'C'.match(reCriminals)[0] == 'C', 'message: Your regex should match <em>one</em> criminal (\"<code>C</code>\") in <code>\"C\"</code>');",
"assert('CC'.match(reCriminals) && 'CC'.match(reCriminals)[0] == 'CC', 'message: Your regex should match <em>two</em> criminals (\"<code>CC</code>\") in <code>\"CC\"</code>');",
"assert('P1P5P4CCCP2P6P3'.match(reCriminals) && 'P1P5P4CCCP2P6P3'.match(reCriminals)[0] == 'CCC', 'message: Your regex should match <em>three</em> criminals (\"<code>CCC</code>\") in <code>\"P1P5P4CCCP2P6P3\"</code>');",
"assert('P6P2P7P4P5CCCCCP3P1'.match(reCriminals) && 'P6P2P7P4P5CCCCCP3P1'.match(reCriminals)[0] == 'CCCCC', 'message: Your regex should match <em>five</em> criminals (\"<code>CCCCC</code>\") in <code>\"P6P2P7P4P5CCCCCP3P1\"</code>');",
"assert(!reCriminals.test(''), 'message: Your regex should not match any criminals in <code>\"\"</code>');",
"assert(!reCriminals.test('P1P2P3'), 'message: Your regex should not match any criminals in <code>\"P1P2P3\"</code>');",
"assert('P2P1P5P4CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCP3'.match(reCriminals) && 'P2P1P5P4CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCP3'.match(reCriminals)[0] == \"CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\", 'message: Your regex should match <em>fifty</em> criminals (\"<code>CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC</code>\") in <code>\"P2P1P5P4CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCP3\"</code>.');"
],
"solutions": [],
"hints": [],
"type": "waypoint",
"releasedOn": "Feb 17, 2017",
"challengeType": 1,
"translations": {}
},
{
"id": "587d7db7367417b2b2512b9d",
"title": "Match Beginning String Patterns",
"description": [
"Prior challenges showed that regular expressions can be used to look for a number of matches. They are also used to search for patterns in specific positions in strings.",
"In an earlier challenge, you used the <code>caret</code> character (<code>^</code>) inside a <code>character set</code> to create a <code>negated character set</code> in the form <code>[^thingsThatWillNotBeMatched]</code>. Outside of a <code>character set</code>, the <code>caret</code> is used to search for patterns at the beginning of strings.",
"<blockquote>let firstString = \"Ricky is first and can be found.\";<br>let firstRegex = /^Ricky/;<br>firstRegex.test(firstString);<br>// Returns true<br>let notFirst = \"You can't find Ricky now.\";<br>firstRegex.test(notFirst);<br>// Returns false</blockquote>",
"<hr>",
"Use the <code>caret</code> character in a regex to find <code>\"Cal\"</code> only in the beginning of the string <code>rickyAndCal</code>."
],
"challengeSeed": [
"let rickyAndCal = \"Cal and Ricky both like racing.\";",
"let calRegex = /change/; // Change this line",
"let result = calRegex.test(rickyAndCal);"
],
"tests": [
"assert(calRegex.source == \"^Cal\", 'message: Your regex should search for <code>\"Cal\"</code> with a capital letter.');",
"assert(calRegex.flags == \"\", 'message: Your regex should not use any flags.');",
"assert(calRegex.test(\"Cal and Ricky both like racing.\"), 'message: Your regex should match <code>\"Cal\"</code> at the beginning of the string.');",
"assert(!calRegex.test(\"Ricky and Cal both like racing.\"), 'message: Your regex should not match <code>\"Cal\"</code> in the middle of a string.');"
],
"solutions": [],
"hints": [],
"type": "waypoint",
"releasedOn": "Feb 17, 2017",
"challengeType": 1,
"translations": {}
},
{
"id": "587d7db7367417b2b2512b9e",
"title": "Match Ending String Patterns",
"description": [
"In the last challenge, you learned to use the <code>caret</code> character to search for patterns at the beginning of strings. There is also a way to search for patterns at the end of strings.",
"You can search the end of strings using the <code>dollar sign</code> character <code>$</code> at the end of the regex.",
"<blockquote>let theEnding = \"This is a never ending story\";<br>let storyRegex = /story$/;<br>storyRegex.test(theEnding);<br>// Returns true<br>let noEnding = \"Sometimes a story will have to end\";<br>storyRegex.test(noEnding);<br>// Returns false<br></blockquote>",
"<hr>",
"Use the anchor character (<code>$</code>) to match the string <code>\"caboose\"</code> at the end of the string <code>caboose</code>."
],
"challengeSeed": [
"let caboose = \"The last car on a train is the caboose\";",
"let lastRegex = /change/; // Change this line",
"let result = lastRegex.test(caboose);"
],
"tests": [
"assert(lastRegex.source == \"caboose$\", 'message: You should search for <code>\"caboose\"</code> with the dollar sign <code>$</code> anchor in your regex.');",
"assert(lastRegex.flags == \"\", 'message: Your regex should not use any flags.');",
"assert(lastRegex.test(\"The last car on a train is the caboose\"), 'message: You should match <code>\"caboose\"</code> at the end of the string <code>\"The last car on a train is the caboose\"</code>');"
],
"solutions": [],
"hints": [],
"type": "waypoint",
"releasedOn": "Feb 17, 2017",
"challengeType": 1,
"translations": {}
},
{
"id": "587d7db7367417b2b2512b9f",
"title": "Match All Letters and Numbers",
"description": [
"Using character classes, you were able to search for all letters of the alphabet with <code>[a-z]</code>. This kind of character class is common enough that there is a shortcut for it, although it includes a few extra characters as well.",
"The closest character class in JavaScript to match the alphabet is <code>\\w</code>. This shortcut is equal to <code>[A-Za-z0-9_]</code>. This character class matches upper and lowercase letters plus numbers. Note, this character class also includes the underscore character (<code>_</code>).",
"<blockquote>let longHand = /[A-Za-z0-9_]+/;<br>let shortHand = /\\w+/;<br>let numbers = \"42\";<br>let varNames = \"important_var\";<br>longHand.test(numbers); // Returns true<br>shortHand.test(numbers); // Returns true<br>longHand.test(varNames); // Returns true<br>shortHand.test(varNames); // Returns true</blockquote>",
"These shortcut character classes are also known as <code>shorthand character classes</code>.",
"<hr>",
"Use the shorthand character class <code>\\w</code> to count the number of alphanumeric characters in various quotes and strings."
],
"challengeSeed": [
"let quoteSample = \"The five boxing wizards jump quickly.\";",
"let alphabetRegexV2 = /change/; // Change this line",
"let result = quoteSample.match(alphabetRegexV2).length;"
],
"tests": [
"assert(alphabetRegexV2.global, 'message: Your regex should use the global flag.');",
"assert(\"The five boxing wizards jump quickly.\".match(alphabetRegexV2).length === 31, 'message: Your regex should find 31 alphanumeric characters in <code>\"The five boxing wizards jump quickly.\"</code>');",
"assert(\"Pack my box with five dozen liquor jugs.\".match(alphabetRegexV2).length === 32, 'message: Your regex should find 32 alphanumeric characters in <code>\"Pack my box with five dozen liquor jugs.\"</code>');",
"assert(\"How vexingly quick daft zebras jump!\".match(alphabetRegexV2).length === 30, 'message: Your regex should find 30 alphanumeric characters in <code>\"How vexingly quick daft zebras jump!\"</code>');",
"assert(\"123 456 7890 ABC def GHI jkl MNO pqr STU vwx YZ.\".match(alphabetRegexV2).length === 36, 'message: Your regex should find 36 alphanumeric characters in <code>\"123 456 7890 ABC def GHI jkl MNO pqr STU vwx YZ.\"</code>');"
],
"solutions": [],
"hints": [],
"type": "waypoint",
"releasedOn": "Feb 17, 2017",
"challengeType": 1,
"translations": {}
},
{
"id": "587d7db8367417b2b2512ba0",
"title": "Match Everything But Letters and Numbers",
"description": [
"You've learned that you can use a shortcut to match alphanumerics <code>[A-Za-z0-9_]</code> using <code>\\w</code>. A natural pattern you might want to search for is the opposite of alphanumerics.",
"You can search for the opposite of the <code>\\w</code> with <code>\\W</code>. Note, the opposite pattern uses a capital letter. This shortcut is the same as <code>[^A-Za-z0-9_]</code>.",
"<blockquote>let shortHand = /\\W/;<br>let numbers = \"42%\";<br>let sentence = \"Coding!\";<br>numbers.match(shortHand); // Returns [\"%\"]<br>sentence.match(shortHand); // Returns [\"!\"]<br></blockquote>",
"<hr>",
"Use the shorthand character class <code>\\W</code> to count the number of non-alphanumeric characters in various quotes and strings."
],
"challengeSeed": [
"let quoteSample = \"The five boxing wizards jump quickly.\";",
"let nonAlphabetRegex = /change/; // Change this line",
"let result = quoteSample.match(nonAlphabetRegex).length;"
],
"tests": [
"assert(nonAlphabetRegex.global, 'message: Your regex should use the global flag.');",
"assert(\"The five boxing wizards jump quickly.\".match(nonAlphabetRegex).length == 6, 'message: Your regex should find 6 non-alphanumeric characters in <code>\"The five boxing wizards jump quickly.\"</code>.');",
"assert(\"Pack my box with five dozen liquor jugs.\".match(nonAlphabetRegex).length == 8, 'message: Your regex should find 8 non-alphanumeric characters in <code>\"Pack my box with five dozen liquor jugs.\"</code>');",
"assert(\"How vexingly quick daft zebras jump!\".match(nonAlphabetRegex).length == 6, 'message: Your regex should find 6 non-alphanumeric characters in <code>\"How vexingly quick daft zebras jump!\"</code>');",
"assert(\"123 456 7890 ABC def GHI jkl MNO pqr STU vwx YZ.\".match(nonAlphabetRegex).length == 12, 'message: Your regex should find 12 non-alphanumeric characters in <code>\"123 456 7890 ABC def GHI jkl MNO pqr STU vwx YZ.\"</code>');"
],
"solutions": [],
"hints": [],
"type": "waypoint",
"releasedOn": "Feb 17, 2017",
"challengeType": 1,
"translations": {}
},
{
"id": "5d712346c441eddfaeb5bdef",
"title": "Match All Numbers",
"description": [
"You've learned shortcuts for common string patterns like alphanumerics. Another common pattern is looking for just digits or numbers.",
"The shortcut to look for digit characters is <code>\\d</code>, with a lowercase <code>d</code>. This is equal to the character class <code>[0-9]</code>, which looks for a single character of any number between zero and nine.",
"<hr>",
"Use the shorthand character class <code>\\d</code> to count how many digits are in movie titles. Written out numbers (\"six\" instead of 6) do not count."
],
"challengeSeed": [
"let numString = \"Your sandwich will be $5.00\";",
"let numRegex = /change/; // Change this line",
"let result = numString.match(numRegex).length;"
],
"tests": [
"assert(/\\\\d/.test(numRegex.source), 'message: Your regex should use the shortcut character to match digit characters');",
"assert(numRegex.global, 'message: Your regex should use the global flag.');",
"assert(\"9\".match(numRegex).length == 1, 'message: Your regex should find 1 digit in <code>\"9\"</code>.');",
"assert(\"Catch 22\".match(numRegex).length == 2, 'message: Your regex should find 2 digits in <code>\"Catch 22\"</code>.');",
"assert(\"101 Dalmatians\".match(numRegex).length == 3, 'message: Your regex should find 3 digits in <code>\"101 Dalmatians\"</code>.');",
"assert(\"One, Two, Three\".match(numRegex) == null, 'message: Your regex should find no digits in <code>\"One, Two, Three\"</code>.');",
"assert(\"21 Jump Street\".match(numRegex).length == 2, 'message: Your regex should find 2 digits in <code>\"21 Jump Street\"</code>.');",
"assert(\"2001: A Space Odyssey\".match(numRegex).length == 4, 'message: Your regex should find 4 digits in <code>\"2001: A Space Odyssey\"</code>.');"
],
"solutions": [],
"hints": [],
"type": "waypoint",
"releasedOn": "Feb 17, 2017",
"challengeType": 1,
"translations": {}
},
{
"id": "587d7db8367417b2b2512ba1",
"title": "Match All Non-Numbers",
"description": [
"The last challenge showed how to search for digits using the shortcut <code>\\d</code> with a lowercase <code>d</code>. You can also search for non-digits using a similar shortcut that uses an uppercase <code>D</code> instead.",
"The shortcut to look for non-digit characters is <code>\\D</code>. This is equal to the character class <code>[^0-9]</code>, which looks for a single character that is not a number between zero and nine.",
"<hr>",
"Use the shorthand character class for non-digits <code>\\D</code> to count how many non-digits are in movie titles."
],
"challengeSeed": [
"let numString = \"Your sandwich will be $5.00\";",
"let noNumRegex = /change/; // Change this line",
"let result = numString.match(noNumRegex).length;"
],
"tests": [
"assert(/\\\\D/.test(noNumRegex.source), 'message: Your regex should use the shortcut character to match non-digit characters');",
"assert(noNumRegex.global, 'message: Your regex should use the global flag.');",
"assert(\"9\".match(noNumRegex) == null, 'message: Your regex should find no non-digits in <code>\"9\"</code>.');",
"assert(\"Catch 22\".match(noNumRegex).length == 6, 'message: Your regex should find 6 non-digits in <code>\"Catch 22\"</code>.');",
"assert(\"101 Dalmatians\".match(noNumRegex).length == 11, 'message: Your regex should find 11 non-digits in <code>\"101 Dalmatians\"</code>.');",
"assert(\"One, Two, Three\".match(noNumRegex).length == 15, 'message: Your regex should find 15 non-digits in <code>\"One, Two, Three\"</code>.');",
"assert(\"21 Jump Street\".match(noNumRegex).length == 12, 'message: Your regex should find 12 non-digits in <code>\"21 Jump Street\"</code>.');",
"assert(\"2001: A Space Odyssey\".match(noNumRegex).length == 17, 'message: Your regex should find 17 non-digits in <code>\"2001: A Space Odyssey\"</code>.');"
],
"solutions": [],
"hints": [],
"type": "waypoint",
"releasedOn": "Feb 17, 2017",
"challengeType": 1,
"translations": {}
},
{
"id": "587d7db8367417b2b2512ba2",
"title": "Restrict Possible Usernames",
"description": [
"Usernames are used everywhere on the internet. They are what give users a unique identity on their favorite sites.",
"You need to check all the usernames in a database. Here are some simple rules that users have to follow when creating their username.",
"1) The only numbers in the username have to be at the end. There can be zero or more of them at the end.",
"2) Username letters can be lowercase and uppercase.",
"3) Usernames have to be at least two characters long. A two-letter username can only use alphabet letter characters.",
"<hr>",
"Change the regex <code>userCheck</code> to fit the constraints listed above."
],
"challengeSeed": [
"let username = \"JackOfAllTrades\";",
"let userCheck = /change/; // Change this line",
"let result = userCheck.test(username);"
],
"tests": [
"assert(userCheck.test(\"JACK\"), 'message: Your regex should match <code>JACK</code>');",
"assert(!userCheck.test(\"J\"), 'message: Your regex should not match <code>J</code>');",
"assert(userCheck.test(\"Oceans11\"), 'message: Your regex should match <code>Oceans11</code>');",
"assert(userCheck.test(\"RegexGuru\"), 'message: Your regex should match <code>RegexGuru</code>');",
"assert(!userCheck.test(\"007\"), 'message: Your regex should not match <code>007</code>');",
"assert(!userCheck.test(\"9\"), 'message: Your regex should not match <code>9</code>');"
],
"solutions": [],
"hints": [],
"type": "waypoint",
"releasedOn": "Feb 17, 2017",
"challengeType": 1,
"translations": {}
},
{
"id": "587d7db8367417b2b2512ba3",
"title": "Match Whitespace",
"description": [
"The challenges so far have covered matching letters of the alphabet and numbers. You can also match the whitespace or spaces between letters.",
"You can search for whitespace using <code>\\s</code>, which is a lowercase <code>s</code>. This pattern not only matches whitespace, but also carriage return, tab, form feed, and new line characters. You can think of it as similar to the character class <code>[ \\r\\t\\f\\n\\v]</code>.",
"<blockquote>let whiteSpace = \"Whitespace. Whitespace everywhere!\"<br>let spaceRegex = /\\s/g;<br>whiteSpace.match(spaceRegex);<br>// Returns [\" \", \" \"]<br></blockquote>",
"<hr>",
"Change the regex <code>countWhiteSpace</code> to look for multiple whitespace characters in a string."
],
"challengeSeed": [
"let sample = \"Whitespace is important in separating words\";",
"let countWhiteSpace = /change/; // Change this line",
"let result = sample.match(countWhiteSpace);"
],
"tests": [
"assert(countWhiteSpace.global, 'message: Your regex should use the global flag.');",
"assert(\"Men are from Mars and women are from Venus.\".match(countWhiteSpace).length == 8, 'message: Your regex should find eight spaces in <code>\"Men are from Mars and women are from Venus.\"</code>');",
"assert(\"Space: the final frontier.\".match(countWhiteSpace).length == 3, 'message: Your regex should find three spaces in <code>\"Space: the final frontier.\"</code>');",
"assert(\"MindYourPersonalSpace\".match(countWhiteSpace) == null, 'message: Your regex should find no spaces in <code>\"MindYourPersonalSpace\"</code>');"
],
"solutions": [],
"hints": [],
"type": "waypoint",
"releasedOn": "Feb 17, 2017",
"challengeType": 1,
"translations": {}
},
{
"id": "587d7db9367417b2b2512ba4",
"title": "Match Non-Whitespace Characters",
"description": [
"You learned about searching for whitespace using <code>\\s</code>, with a lowercase <code>s</code>. You can also search for everything except whitespace.",
"Search for non-whitespace using <code>\\S</code>, which is an uppercase <code>s</code>. This pattern will not match whitespace, carriage return, tab, form feed, and new line characters. You can think of it being similar to the character class <code>[^ \\r\\t\\f\\n\\v]</code>.",
"<blockquote>let whiteSpace = \"Whitespace. Whitespace everywhere!\"<br>let nonSpaceRegex = /\\S/g;<br>whiteSpace.match(nonSpaceRegex).length; // Returns 32</blockquote>",
"<hr>",
"Change the regex <code>countNonWhiteSpace</code> to look for multiple non-whitespace characters in a string."
],
"challengeSeed": [
"let sample = \"Whitespace is important in separating words\";",
"let countNonWhiteSpace = /change/; // Change this line",
"let result = sample.match(countNonWhiteSpace);"
],
"tests": [
"assert(countNonWhiteSpace.global, 'message: Your regex should use the global flag.');",
"assert(\"Men are from Mars and women are from Venus.\".match(countNonWhiteSpace).length == 35, 'message: Your regex should find 35 non-spaces in <code>\"Men are from Mars and women are from Venus.\"</code>');",
"assert(\"Space: the final frontier.\".match(countNonWhiteSpace).length == 23, 'message: Your regex should find 23 non-spaces in <code>\"Space: the final frontier.\"</code>');",
"assert(\"MindYourPersonalSpace\".match(countNonWhiteSpace).length == 21, 'message: Your regex should find 21 non-spaces in <code>\"MindYourPersonalSpace\"</code>');"
],
"solutions": [],
"hints": [],
"type": "waypoint",
"releasedOn": "Feb 17, 2017",
"challengeType": 1,
"translations": {}
},
{
"id": "587d7db9367417b2b2512ba5",
"title": "Specify Upper and Lower Number of Matches",
"description": [
"Recall that you use the plus sign <code>+</code> to look for one or more characters and the asterisk <code>*</code> to look for zero or more characters. These are convenient but sometimes you want to match a certain range of patterns.",
"You can specify the lower and upper number of patterns with <code>quantity specifiers</code>. Quantity specifiers are used with curly brackets (<code>{</code> and <code>}</code>). You put two numbers between the curly brackets - for the lower and upper number of patterns.",
"For example, to match only the letter <code>a</code> appearing between <code>3</code> and <code>5</code> times in the string <code>\"ah\"</code>, your regex would be <code>/a{3,5}h/</code>.",
"<blockquote>let A4 = \"aaaah\";<br>let A2 = \"aah\";<br>let multipleA = /a{3,5}h/;<br>multipleA.test(A4); // Returns true<br>multipleA.test(A2); // Returns false</blockquote>",
"<hr>",
"Change the regex <code>ohRegex</code> to match only <code>3</code> to <code>6</code> letter <code>h</code>'s in the word <code>\"Oh no\"</code>."
],
"challengeSeed": [
"let ohStr = \"Ohhh no\";",
"let ohRegex = /change/; // Change this line",
"let result = ohRegex.test(ohStr);"
],
"tests": [
"assert(ohRegex.source.match(/{.*?}/).length > 0, 'message: Your regex should use curly brackets.');",
"assert(!ohRegex.test(\"Ohh no\"), 'message: Your regex should not match <code>\"Ohh no\"</code>');",
"assert(ohRegex.test(\"Ohhh no\"), 'message: Your regex should match <code>\"Ohhh no\"</code>');",
"assert(ohRegex.test(\"Ohhhh no\"), 'message: Your regex should match <code>\"Ohhhh no\"</code>');",
"assert(ohRegex.test(\"Ohhhhh no\"), 'message: Your regex should match <code>\"Ohhhhh no\"</code>');",
"assert(ohRegex.test(\"Ohhhhhh no\"), 'message: Your regex should match <code>\"Ohhhhhh no\"</code>');",
"assert(!ohRegex.test(\"Ohhhhhhh no\"), 'message: Your regex should not match <code>\"Ohhhhhhh no\"</code>');"
],
"solutions": [],
"hints": [],
"type": "waypoint",
"releasedOn": "Feb 17, 2017",
"challengeType": 1,
"translations": {}
},
{
"id": "587d7db9367417b2b2512ba6",
"title": "Specify Only the Lower Number of Matches",
"description": [
"You can specify the lower and upper number of patterns with <code>quantity specifiers</code> using curly brackets. Sometimes you only want to specify the lower number of patterns with no upper limit.",
"To only specify the lower number of patterns, keep the first number followed by a comma.",
"For example, to match only the string <code>\"hah\"</code> with the letter <code>a</code> appearing at least <code>3</code> times, your regex would be <code>/ha{3,}h/</code>.",
"<blockquote>let A4 = \"haaaah\";<br>let A2 = \"haah\";<br>let A100 = \"h\" + \"a\".repeat(100) + \"h\";<br>let multipleA = /ha{3,}h/;<br>multipleA.test(A4); // Returns true<br>multipleA.test(A2); // Returns false<br>multipleA.test(A100); // Returns true</blockquote>",
"<hr>",
"Change the regex <code>haRegex</code> to match the word <code>\"Hazzah\"</code> only when it has four or more letter <code>z</code>'s."
],
"challengeSeed": [
"let haStr = \"Hazzzzah\";",
"let haRegex = /change/; // Change this line",
"let result = haRegex.test(haStr);"
],
"tests": [
"assert(haRegex.source.match(/{.*?}/).length > 0, 'message: Your regex should use curly brackets.');",
"assert(!haRegex.test(\"Hazzah\"), 'message: Your regex should not match <code>\"Hazzah\"</code>');",
"assert(!haRegex.test(\"Hazzzah\"), 'message: Your regex should not match <code>\"Hazzzah\"</code>');",
"assert(haRegex.test(\"Hazzzzah\"), 'message: Your regex should match <code>\"Hazzzzah\"</code>');",
"assert(haRegex.test(\"Hazzzzzah\"), 'message: Your regex should match <code>\"Hazzzzzah\"</code>');",
"assert(haRegex.test(\"Hazzzzzzah\"), 'message: Your regex should match <code>\"Hazzzzzzah\"</code>');",
"assert(haRegex.test(\"Ha\" + \"z\".repeat(30) + \"ah\"), 'message: Your regex should match <code>\"Hazzah\"</code> with 30 <code>z</code>\\'s in it.');"
],
"solutions": [],
"hints": [],
"type": "waypoint",
"releasedOn": "Feb 17, 2017",
"challengeType": 1,
"translations": {}
},
{
"id": "587d7db9367417b2b2512ba7",
"title": "Specify Exact Number of Matches",
"description": [
"You can specify the lower and upper number of patterns with <code>quantity specifiers</code> using curly brackets. Sometimes you only want a specific number of matches.",
"To specify a certain number of patterns, just have that one number between the curly brackets.",
"For example, to match only the word <code>\"hah\"</code> with the letter <code>a</code> <code>3</code> times, your regex would be <code>/ha{3}h/</code>.",
"<blockquote>let A4 = \"haaaah\";<br>let A3 = \"haaah\";<br>let A100 = \"h\" + \"a\".repeat(100) + \"h\";<br>let multipleHA = /a{3}h/;<br>multipleHA.test(A4); // Returns false<br>multipleHA.test(A3); // Returns true<br>multipleHA.test(A100); // Returns false</blockquote>",
"<hr>",
"Change the regex <code>timRegex</code> to match the word <code>\"Timber\"</code> only when it has four letter <code>m</code>'s."
],
"challengeSeed": [
"let timStr = \"Timmmmber\";",
"let timRegex = /change/; // Change this line",
"let result = timRegex.test(timStr);"
],
"tests": [
"assert(timRegex.source.match(/{.*?}/).length > 0, 'message: Your regex should use curly brackets.');",
"assert(!timRegex.test(\"Timber\"), 'message: Your regex should not match <code>\"Timber\"</code>');",
"assert(!timRegex.test(\"Timmber\"), 'message: Your regex should not match <code>\"Timmber\"</code>');",
"assert(!timRegex.test(\"Timmmber\"), 'message: Your regex should not match <code>\"Timmmber\"</code>');",
"assert(timRegex.test(\"Timmmmber\"), 'message: Your regex should match <code>\"Timmmmber\"</code>');",
"assert(!timRegex.test(\"Ti\" + \"m\".repeat(30) + \"ber\"), 'message: Your regex should not match <code>\"Timber\"</code> with 30 <code>m</code>\\'s in it.');"
],
"solutions": [],
"hints": [],
"type": "waypoint",
"releasedOn": "Feb 17, 2017",
"challengeType": 1,
"translations": {}
},
{
"id": "587d7dba367417b2b2512ba8",
"title": "Check for All or None",
"description": [
"Sometimes the patterns you want to search for may have parts of it that may or may not exist. However, it may be important to check for them nonetheless.",
"You can specify the possible existence of an element with a question mark, <code>?</code>. This checks for zero or one of the preceding element. You can think of this symbol as saying the previous element is optional.",
"For example, there are slight differences in American and British English and you can use the question mark to match both spellings.",
"<blockquote>let american = \"color\";<br>let british = \"colour\";<br>let rainbowRegex= /colou?r/;<br>rainbowRegex.test(american); // Returns true<br>rainbowRegex.test(british); // Returns true</blockquote>",
"<hr>",
"Change the regex <code>favRegex</code> to match both the American English (favorite) and the British English (favourite) version of the word."
],
"challengeSeed": [
"let favWord = \"favorite\";",
"let favRegex = /change/; // Change this line",
"let result = favRegex.test(favWord);"
],
"tests": [
"assert(favRegex.source.match(/\\?/).length > 0, 'message: Your regex should use the optional symbol, <code>?</code>.');",
"assert(favRegex.test(\"favorite\"), 'message: Your regex should match <code>\"favorite\"</code>');",
"assert(favRegex.test(\"favourite\"), 'message: Your regex should match <code>\"favourite\"</code>');",
"assert(!favRegex.test(\"fav\"), 'message: Your regex should not match <code>\"fav\"</code>');"
],
"solutions": [],
"hints": [],
"type": "waypoint",
"releasedOn": "Feb 17, 2017",
"challengeType": 1,
"translations": {}
},
{
"id": "587d7dba367417b2b2512ba9",
"title": "Positive and Negative Lookahead",
"description": [
"<code>Lookaheads</code> are patterns that tell JavaScript to look-ahead in your string to check for patterns further along. This can be useful when you want to search for multiple patterns over the same string.",
"There are two kinds of <code>lookaheads</code>: <code>positive lookahead</code> and <code>negative lookahead</code>.",
"A <code>positive lookahead</code> will look to make sure the element in the search pattern is there, but won't actually match it. A positive lookahead is used as <code>(?=...)</code> where the <code>...</code> is the required part that is not matched.",
"On the other hand, a <code>negative lookahead</code> will look to make sure the element in the search pattern is not there. A negative lookahead is used as <code>(?!...)</code> where the <code>...</code> is the pattern that you do not want to be there. The rest of the pattern is returned if the negative lookahead part is not present.",
"Lookaheads are a bit confusing but some examples will help.",
"<blockquote>let quit = \"qu\";<br>let noquit = \"qt\";<br>let quRegex= /q(?=u)/;<br>let qRegex = /q(?!u)/;<br>quit.match(quRegex); // Returns [\"q\"]<br>noquit.match(qRegex); // Returns [\"q\"]</blockquote>",
"A more practical use of <code>lookaheads</code> is to check two or more patterns in one string. Here is a (naively) simple password checker that looks for between 3 and 6 characters and at least one number:",
"<blockquote>let password = \"abc123\";<br>let checkPass = /(?=\\w{3,6})(?=\\D*\\d)/;<br>checkPass.test(password); // Returns true</blockquote>",
"<hr>",
"Use <code>lookaheads</code> in the <code>pwRegex</code> to match passwords that are greater than 5 characters long and have two consecutive digits."
],
"challengeSeed": [
"let sampleWord = \"astronaut\";",
"let pwRegex = /change/; // Change this line",
"let result = pwRegex.test(sampleWord);"
],
"tests": [
"assert(pwRegex.source.match(/\\(\\?=.*?\\)\\(\\?=.*?\\)/) !== null, 'message: Your regex should use two positive <code>lookaheads</code>.');",
"assert(!pwRegex.test(\"astronaut\"), 'message: Your regex should not match <code>\"astronaut\"</code>');",
"assert(!pwRegex.test(\"airplanes\"), 'message: Your regex should not match <code>\"airplanes\"</code>');",
"assert(pwRegex.test(\"bana12\"), 'message: Your regex should match <code>\"bana12\"</code>');",
"assert(pwRegex.test(\"abc123\"), 'message: Your regex should match <code>\"abc123\"</code>');",
"assert(!pwRegex.test(\"123\"), 'message: Your regex should not match <code>\"123\"</code>');",
"assert(!pwRegex.test(\"1234\"), 'message: Your regex should not match <code>\"1234\"</code>');"
],
"solutions": [],
"hints": [],
"type": "waypoint",
"releasedOn": "Feb 17, 2017",
"challengeType": 1,
"translations": {}
},
{
"id": "587d7dbb367417b2b2512baa",
"title": "Reuse Patterns Using Capture Groups",
"description": [
"Some patterns you search for will occur multiple times in a string. It is wasteful to manually repeat that regex. There is a better way to specify when you have multiple repeat substrings in your string.",
"You can search for repeat substrings using <code>capture groups</code>. Parentheses, <code>(</code> and <code>)</code>, are used to find repeat substrings. You put the regex of the pattern that will repeat in between the parentheses.",
"To specify where that repeat string will appear, you use a backslash (<code>\\</code>) and then a number. This number starts at 1 and increases with each additional capture group you use. An example would be <code>\\1</code> to match the first group.",
"The example below matches any word that occurs twice separated by a space:",
"<blockquote>let repeatStr = \"regex regex\";<br>let repeatRegex = /(\\w+)\\s\\1/;<br>repeatRegex.test(repeatStr); // Returns true<br>repeatStr.match(repeatRegex); // Returns [\"regex regex\", \"regex\"]</blockquote>",
"Using the <code>.match()</code> method on a string will return an array with the string it matches, along with its capture group.",
"<hr>",
"Use <code>capture groups</code> in <code>reRegex</code> to match numbers that are repeated only three times in a string, each separated by a space."
],
"challengeSeed": [
"let repeatNum = \"42 42 42\";",
"let reRegex = /change/; // Change this line",
"let result = reRegex.test(repeatNum);"
],
"tests": [
"assert(reRegex.source.match(/\\\\d/), 'message: Your regex should use the shorthand character class for digits.');",
"assert(reRegex.source.match(/\\\\\\d/g).length === 2, 'message: Your regex should reuse the capture group twice.');",
"assert(reRegex.source.match(/\\\\s/g).length === 2, 'message: Your regex should have two spaces separating the three numbers.');",
"assert(reRegex.test(\"42 42 42\"), 'message: Your regex should match <code>\"42 42 42\"</code>.');",
"assert(reRegex.test(\"100 100 100\"), 'message: Your regex should match <code>\"100 100 100\"</code>.');",
"assert.equal((\"42 42 42 42\").match(reRegex.source), null, 'message: Your regex should not match <code>\"42 42 42 42\"</code>.');",
"assert.equal((\"42 42\").match(reRegex.source), null, 'message: Your regex should not match <code>\"42 42\"</code>.');",
"assert(!reRegex.test(\"101 102 103\"), 'message: Your regex should not match <code>\"101 102 103\"</code>.');",
"assert(!reRegex.test(\"1 2 3\"), 'message: Your regex should not match <code>\"1 2 3\"</code>.');",
"assert(reRegex.test(\"10 10 10\"), 'message: Your regex should match <code>\"10 10 10\"</code>.');"
],
"solutions": [],
"hints": [],
"type": "waypoint",
"releasedOn": "Feb 17, 2017",
"challengeType": 1,
"translations": {}
},
{
"id": "587d7dbb367417b2b2512bab",
"title": "Use Capture Groups to Search and Replace",
"description": [
"Searching is useful. However, you can make searching even more powerful when it also changes (or replaces) the text you match.",
"You can search and replace text in a string using <code>.replace()</code> on a string. The inputs for <code>.replace()</code> is first the regex pattern you want to search for. The second parameter is the string to replace the match or a function to do something.",
"<blockquote>let wrongText = \"The sky is silver.\";<br>let silverRegex = /silver/;<br>wrongText.replace(silverRegex, \"blue\");<br>// Returns \"The sky is blue.\"</blockquote>",
"You can also access capture groups in the replacement string with dollar signs (<code>$</code>).",
"<blockquote>\"Code Camp\".replace(/(\\w+)\\s(\\w+)/, '$2 $1');<br>// Returns \"Camp Code\"</blockquote>",
"<hr>",
"Write a regex so that it will search for the string <code>\"good\"</code>. Then update the <code>replaceText</code> variable to replace <code>\"good\"</code> with <code>\"okey-dokey\"</code>."
],
"challengeSeed": [
"let huhText = \"This sandwich is good.\";",
"let fixRegex = /change/; // Change this line",
"let replaceText = \"\"; // Change this line",
"let result = huhText.replace(fixRegex, replaceText);"
],
"tests": [
"assert(code.match(/\\.replace\\(.*\\)/), 'message: You should use <code>.replace()</code> to search and replace.');",
"assert(result == \"This sandwich is okey-dokey.\" && replaceText === \"okey-dokey\", 'message: Your regex should change <code>\"This sandwich is good.\"</code> to <code>\"This sandwich is okey-dokey.\"</code>');",
"assert(code.match(/result\\s*=\\s*huhText\\.replace\\(.*?\\)/), 'message: You should not change the last line.');"
],
"solutions": [],
"hints": [],
"type": "waypoint",
"releasedOn": "Feb 17, 2017",
"challengeType": 1,
"translations": {}
},
{
"id": "587d7dbb367417b2b2512bac",
"title": "Remove Whitespace from Start and End",
"description": [
"Sometimes whitespace characters around strings are not wanted but are there. Typical processing of strings is to remove the whitespace at the start and end of it.",
"<hr>",
"Write a regex and use the appropriate string methods to remove whitespace at the beginning and end of strings.",
"<strong>Note</strong><br>The <code>.trim()</code> method would work here, but you'll need to complete this challenge using regular expressions."
],
"challengeSeed": [
"let hello = \" Hello, World! \";",
"let wsRegex = /change/; // Change this line",
"let result = hello; // Change this line"
],
"tests": [
"assert(result == \"Hello, World!\", 'message: <code>result</code> should equal to <code>\"Hello, World!\"</code>');",
"assert(!code.match(/\\.trim\\(.*?\\)/), 'message: You should not use the <code>.trim()</code> method.');",
"assert(!code.match(/result\\s*=\\s*\".*?\"/), 'message: The <code>result</code> variable should not be set equal to a string.');"
],
"solutions": [],
"hints": [
"You can use .replace() to remove the matched items by replacing them with an empty string."
],
"type": "waypoint",
"releasedOn": "Feb 17, 2017",
"challengeType": 1,
"translations": {}
}
]
}