freeCodeCamp/seed/challenges/02-javascript-algorithms-an.../basic-data-structures.json

827 lines
64 KiB
JSON
Raw Normal View History

2017-01-17 04:44:38 +00:00
{
2017-01-20 01:19:33 +00:00
"name": "Basic Data Structures",
2017-01-17 04:44:38 +00:00
"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": "",
"challengeSeed": [],
"tests": [],
"type": "Waypoint",
"challengeType": 7,
"isRequired": false,
"titleEs": "",
"descriptionEs": [
[]
],
"titleFr": "",
"descriptionFr": [
[]
],
"titleDe": "",
"descriptionDe": [
[]
]
},
{
"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",
"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 (1st index) 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[0]</code> is equal to <code>\"c\"</code>');",
"assert.strictEqual(myArray[3], \"d\", 'message: <code>myArray[0]</code> is equal to <code>\"d\"</code>');"
],
"type": "waypoint",
"solutions": [],
"challengeType": 1,
"translations": {}
},
2017-01-17 04:44:38 +00:00
{
"id": "587d78b2367417b2b2512b0e",
"title": "Add Items to an Array with push() and unshift()",
2017-01-17 04:44:38 +00:00
"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']",
2017-01-17 04:44:38 +00:00
"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>shift()</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."
2017-01-17 04:44:38 +00:00
],
"challengeSeed": [
"function mixedNumbers(arr) {",
" // change code below this line",
"",
" // change code above this line",
" return arr;",
2017-01-17 04:44:38 +00:00
"}",
"",
2017-01-17 04:44:38 +00:00
"// do not change code below this line",
"console.log(mixedNumbers(['IV', 5, 'six']));"
2017-01-17 04:44:38 +00:00
],
"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');"
2017-01-17 04:44:38 +00:00
],
"type": "waypoint",
"solutions": [],
"challengeType": 1,
2017-01-17 04:44:38 +00:00
"translations": {}
},
{
"id": "587d78b2367417b2b2512b0f",
"title": "Remove Items from an Array with pop() and shift()",
2017-01-17 04:44:38 +00:00
"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.",
2017-01-17 04:44:38 +00:00
"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>",
2017-01-17 04:44:38 +00:00
"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."
2017-01-17 04:44:38 +00:00
],
"challengeSeed": [
"function popShift(arr) {",
" let popped; // change this line",
" let shifted; // change this line",
" return [shifted, popped];",
2017-01-17 04:44:38 +00:00
"}",
"",
2017-01-17 04:44:38 +00:00
"// do not change code below this line",
"console.log(popShift(['challenge', 'is', 'not', 'complete']));"
2017-01-17 04:44:38 +00:00
],
"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');"
2017-01-17 04:44:38 +00:00
],
"type": "waypoint",
"solutions": [],
"challengeType": 1,
2017-01-17 04:44:38 +00:00
"translations": {}
},
{
"id": "587d78b2367417b2b2512b10",
"title": "Remove Items Using splice()",
2017-01-17 04:44:38 +00:00
"description": [
"Ok, so we've learned how to remove elements from the beginning and end of arrays using <code>pop()</code> and <code>shift()</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 on 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>."
2017-01-17 04:44:38 +00:00
],
"challengeSeed": [
"function sumOfTen(arr) {",
" // change code below this line",
"",
" // change code above this line",
" return arr.reduce((a, b) => a + b);",
2017-01-17 04:44:38 +00:00
"}",
"",
2017-01-17 04:44:38 +00:00
"// do not change code below this line",
"console.log(sumOfTen([2, 5, 1, 5, 2, 1]));"
2017-01-17 04:44:38 +00:00
],
"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');"
2017-01-17 04:44:38 +00:00
],
"type": "waypoint",
"solutions": [],
"challengeType": 1,
2017-01-17 04:44:38 +00:00
"translations": {}
},
{
"id": "587d78b3367417b2b2512b11",
"title": "Add Items Using splice()",
2017-01-17 04:44:38 +00:00
"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."
2017-01-17 04:44:38 +00:00
],
"challengeSeed": [
"function htmlColorNames(arr) {",
" // change code below this line",
" ",
" // change code above this line",
" return arr;",
2017-01-17 04:44:38 +00:00
"} ",
" ",
2017-01-17 04:44:38 +00:00
"// do not change code below this line",
"console.log(htmlColorNames(['DarkGoldenRod', 'WhiteSmoke', 'LavenderBlush', 'PaleTurqoise', 'FireBrick']));"
2017-01-17 04:44:38 +00:00
],
"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.notStrictEqual(htmlColorNames.toString().search(/\\.splice\\(/), -1, 'message: The <code>htmlColorNames</code> function should utilize the <code>splice()</code> method');"
2017-01-17 04:44:38 +00:00
],
"type": "waypoint",
"solutions": [],
"challengeType": 1,
2017-01-17 04:44:38 +00:00
"translations": {}
},
{
"id": "587d7b7a367417b2b2512b12",
"title": "Copy an Array with slice()",
2017-01-17 04:44:38 +00:00
"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>",
2017-01-17 04:44:38 +00:00
"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>."
2017-01-17 04:44:38 +00:00
],
"challengeSeed": [
"function forecast(arr) {",
" // change code below this line",
2017-01-17 04:44:38 +00:00
" ",
" return arr;",
2017-01-17 04:44:38 +00:00
"}",
"",
2017-01-17 04:44:38 +00:00
"// do not change code below this line",
"console.log(forecast(['cold', 'rainy', 'warm', 'sunny', 'cool', 'thunderstorms']));"
2017-01-17 04:44:38 +00:00
],
"tests": [
"assert.deepEqual(forecast(['cold', 'rainy', 'warm', 'sunny', 'cool', 'thunderstorms']), ['warm', 'sunny'], 'message: <code>forecast</code> should return <code>[\"warm\", \"sunny\"]');",
"assert.notStrictEqual(forecast.toString().search(/\\.slice\\(/), -1, 'message: The <code>forecast</code> function should utilize the <code>slice()</code> method');"
2017-01-17 04:44:38 +00:00
],
"type": "waypoint",
"solutions": [],
"challengeType": 1,
2017-01-17 04:44:38 +00:00
"translations": {}
},
{
"id": "587d7b7b367417b2b2512b13",
"title": "Copy an Array with the Spread Operator",
2017-01-17 04:44:38 +00:00
"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!)."
2017-01-17 04:44:38 +00:00
],
"challengeSeed": [
"function copyMachine(arr, num) {",
" let newArr = [];",
" while (num >= 1) {",
" // change code below this line",
"",
" // change code above this line",
" num--;",
" }",
" return newArr;",
2017-01-17 04:44:38 +00:00
"}",
"",
"// change code here to test different cases:",
"console.log(copyMachine([true, false, true], 2));"
2017-01-17 04:44:38 +00:00
],
"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().search(/[...]/), -1, 'message: The <code>copyMachine</code> function should utilize the <code>...</code> operator');"
2017-01-17 04:44:38 +00:00
],
"type": "waypoint",
"solutions": [],
"challengeType": 1,
2017-01-17 04:44:38 +00:00
"translations": {}
},
{
"id": "587d7b7b367417b2b2512b17",
"title": "Combine Arrays with the Spread Operator",
2017-01-17 04:44:38 +00:00
"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>."
2017-01-17 04:44:38 +00:00
],
"challengeSeed": [
"function spreadOut() {",
" let fragment = ['to', 'code'];",
" let sentence; // change this line",
" return sentence;",
"}",
"",
"// do not change code below this line",
"console.log(spreadOut());"
2017-01-17 04:44:38 +00:00
],
"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');"
2017-01-17 04:44:38 +00:00
],
"type": "waypoint",
"solutions": [],
"challengeType": 1,
2017-01-17 04:44:38 +00:00
"translations": {}
},
{
"id": "587d7b7b367417b2b2512b14",
"title": "Check For The Presence of an Element With indexOf()",
2017-01-17 04:44:38 +00:00
"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.",
2017-01-17 04:44:38 +00:00
"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."
2017-01-17 04:44:38 +00:00
],
"challengeSeed": [
"function quickCheck(arr, elem) {",
" // change code below this line",
"",
" // change code above this line",
2017-01-17 04:44:38 +00:00
"}",
"",
"// change code here to test different cases:",
"console.log(quickCheck(['squash', 'onions', 'shallots'], 'mushrooms'));"
2017-01-17 04:44:38 +00:00
],
"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');"
2017-01-17 04:44:38 +00:00
],
"type": "waypoint",
"solutions": [],
"challengeType": 1,
2017-01-17 04:44:38 +00:00
"translations": {}
},
{
"id": "587d7b7b367417b2b2512b15",
"title": "Iterate Through All an Array's Items Using For Loops",
2017-01-17 04:44:38 +00:00
"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."
2017-01-17 04:44:38 +00:00
],
"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));"
2017-01-17 04:44:38 +00:00
],
"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');"
2017-01-17 04:44:38 +00:00
],
"type": "waypoint",
"solutions": [],
"challengeType": 1,
2017-01-17 04:44:38 +00:00
"translations": {}
},
{
"id": "587d7b7b367417b2b2512b16",
"title": "Create complex multi-dimensional arrays",
2017-01-17 04:44:38 +00:00
"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>."
2017-01-17 04:44:38 +00:00
],
"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",
"];"
2017-01-17 04:44:38 +00:00
],
"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');"
2017-01-17 04:44:38 +00:00
],
"type": "waypoint",
"solutions": [],
"challengeType": 1,
2017-01-17 04:44:38 +00:00
"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": "",
"challengeSeed": [],
"tests": [],
"type": "Waypoint",
"challengeType": 7,
"isRequired": false,
"titleEs": "",
"descriptionEs": [
[]
],
"titleFr": "",
"descriptionFr": [
[]
],
"titleDe": "",
"descriptionDe": [
[]
]
},
2017-01-17 04:44:38 +00:00
{
"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>."
2017-01-17 04:44:38 +00:00
],
"challengeSeed": [
"let foods = {",
" apples: 25,",
" oranges: 32,",
" plums: 28",
"};",
"",
"// change code below this line",
"",
"// change code above this line",
"",
"console.log(foods);"
2017-01-17 04:44:38 +00:00
],
"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');"
2017-01-17 04:44:38 +00:00
],
"type": "waypoint",
"solutions": [],
"challengeType": 1,
2017-01-17 04:44:38 +00:00
"translations": {}
},
{
"id": "587d7b7c367417b2b2512b19",
"title": "Modify an Object Nested Within an Object",
2017-01-17 04:44:38 +00:00
"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>."
2017-01-17 04:44:38 +00:00
],
"challengeSeed": [
"let userActivity = {",
2017-01-17 04:44:38 +00:00
" id: 23894201352,",
" date: 'January 1, 2017',",
" data: {",
" totalUsers: 51,",
" online: 42",
" }",
"};",
"",
"// change code below this line",
"",
"// change code above this line",
"",
"console.log(userActivity);"
2017-01-17 04:44:38 +00:00
],
"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');"
2017-01-17 04:44:38 +00:00
],
"type": "waypoint",
"solutions": [],
"challengeType": 1,
2017-01-17 04:44:38 +00:00
"translations": {}
},
{
"id": "587d7b7c367417b2b2512b1a",
"title": "Access Property Names with Bracket Notation",
2017-01-17 04:44:38 +00:00
"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>."
2017-01-17 04:44:38 +00:00
],
"challengeSeed": [
"let foods = {",
" apples: 25,",
" oranges: 32,",
" plums: 28,",
" bananas: 13,",
" grapes: 35,",
" strawberries: 27",
"};",
"// do not change code above this line",
"",
2017-01-17 04:44:38 +00:00
"function checkInventory(scannedItem) {",
" // change code below this line",
"",
"}",
"",
"// change code below this line to test different cases:",
"console.log(checkInventory(\"apples\"));"
2017-01-17 04:44:38 +00:00
],
"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>');"
2017-01-17 04:44:38 +00:00
],
"type": "waypoint",
"solutions": [],
"challengeType": 1,
2017-01-17 04:44:38 +00:00
"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."
2017-01-17 04:44:38 +00:00
],
"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);"
2017-01-17 04:44:38 +00:00
],
"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>');"
2017-01-17 04:44:38 +00:00
],
"type": "waypoint",
"solutions": [],
"challengeType": 1,
2017-01-17 04:44:38 +00:00
"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."
2017-01-17 04:44:38 +00:00
],
"challengeSeed": [
"let users = {",
" Alan: {",
" age: 27,",
" online: true",
" },",
" Jeff: {",
" age: 32,",
" online: true",
" },",
" Sarah: {",
" age: 48,",
" online: true",
" },",
" Ryan: {",
" age: 19,",
" online: true",
" }",
"};",
"",
2017-01-17 04:44:38 +00:00
"function isEveryoneHere(obj) {",
" // change code below this line",
"",
2017-01-17 04:44:38 +00:00
" // change code above this line",
"}",
"",
"console.log(isEveryoneHere(users));"
2017-01-17 04:44:38 +00:00
],
"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');"
2017-01-17 04:44:38 +00:00
],
"type": "waypoint",
"solutions": [],
"challengeType": 1,
2017-01-17 04:44:38 +00:00
"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>."
2017-01-17 04:44:38 +00:00
],
"challengeSeed": [
"let users = {",
" Alan: {",
" age: 27,",
" online: false",
" },",
" Jeff: {",
" age: 32,",
" online: true",
" },",
" Sarah: {",
" age: 48,",
" online: false",
" },",
" Ryan: {",
" age: 19,",
" online: true",
" }",
"};",
"",
2017-01-17 04:44:38 +00:00
"function countOnline(obj) {",
" // change code below this line",
"",
2017-01-17 04:44:38 +00:00
" // change code above this line",
"}",
"",
"console.log(countOnline(users));"
2017-01-17 04:44:38 +00:00
],
"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>');"
2017-01-17 04:44:38 +00:00
],
"type": "waypoint",
"solutions": [],
"challengeType": 1,
2017-01-17 04:44:38 +00:00
"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."
2017-01-17 04:44:38 +00:00
],
"challengeSeed": [
"let users = {",
" Alan: {",
" age: 27,",
" online: false",
" },",
" Jeff: {",
" age: 32,",
" online: true",
" },",
" Sarah: {",
" age: 48,",
" online: false",
" },",
" Ryan: {",
" age: 19,",
" online: true",
" }",
"};",
"",
2017-01-17 04:44:38 +00:00
"function getArrayOfUsers(obj) {",
" // change code below this line",
"",
2017-01-17 04:44:38 +00:00
" // change code above this line",
"}",
"",
"console.log(getArrayOfUsers(users));"
2017-01-17 04:44:38 +00:00
],
"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');"
2017-01-17 04:44:38 +00:00
],
"type": "waypoint",
"solutions": [],
"challengeType": 1,
2017-01-17 04:44:38 +00:00
"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."
2017-01-17 04:44:38 +00:00
],
"challengeSeed": [
"let user = {",
" name: 'Kenneth',",
" age: 28,",
" data: {",
" username: 'kennethCodesAllDay',",
" joinDate: 'March 26, 2016',",
" organization: 'Free Code Camp',",
" friends: [",
" 'Sam',",
" 'Kira',",
" 'Tomo'",
" ],",
" location: {",
" city: 'San Francisco',",
" state: 'CA',",
" country: 'USA'",
" }",
" }",
"};",
"",
"function addFriend(userObj, friend) {",
2017-01-17 04:44:38 +00:00
" // change code below this line ",
"",
2017-01-17 04:44:38 +00:00
" // change code above this line",
"}",
"",
"console.log(addFriend(user, 'Pete'));"
2017-01-17 04:44:38 +00:00
],
"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>');"
2017-01-17 04:44:38 +00:00
],
"type": "waypoint",
"solutions": [],
"challengeType": 1,
2017-01-17 04:44:38 +00:00
"translations": {}
}
]
2017-01-20 01:19:33 +00:00
}