Write a function called mergeArrays that combines two arrays into one.
mergeArrays(['Rattata', 'Raticate'], ['Bulbasaur', 'Ivysaur', 'Venusaur'])// returns ["Rattata", "Raticate", "Bulbasaur", "Ivysaur", "Venusaur"]
Tests
Remember how this works? Create a solution file (like preflight.js) and a
test file (like preflight.test.js). Make sure your solution file
module.exports an object with all the functions, and your test file
requires the solution file and gives the object a name (we use fn in our
tests).
describe('mergeArrays function', () => {it('should merge 2 arrays of strings', () => {const arr1 = ['Rattata', 'Raticate']const arr2 = ['Bulbasaur', 'Ivysaur', 'Venusaur']const result = fn.mergeArrays(arr1, arr2)expect(result).toEqual(['Rattata','Raticate','Bulbasaur','Ivysaur','Venusaur'])})it('should merge two arrays of numbers', () => {const result = fn.mergeArrays([9, 3, 5], [10])expect(result).toEqual([9, 3, 5, 10])})it('should merge an empty array', () => {const result = fn.mergeArrays(['Pikachu', 'Raichu'], [])expect(result).toEqual(['Pikachu', 'Raichu'])})})
Shape
const mergeArrays = (arr1, arr1) => {}
Explanation
arr1 and array arr2.[...a...b] to combine arrays a and b.arr1 and arr2 in it.Code
const mergeArrays = (arr1, arr2) => {return [...arr1, ...arr2]}
Write a function called firstLongerThan that finds the first string in an array longer than the given number.
firstLongerThan(['Ekans', 'Arbok', 'Pikachu', 'Raichu'], 5) // returns "Pikachu"
Tests
describe('firstLongerThan function', () => {it('should find a string in the middle of an array', () => {const arr = ['Ekans', 'Arbok', 'Pikachu', 'Raichu']const result = fn.firstLongerThan(arr, 5)expect(result).toEqual('Pikachu')})it('should find a string at the end of an array', () => {const arr = ['Caterpie', 'Metapod', 'Butterfree']const result = fn.firstLongerThan(arr, 9)expect(result).toEqual('Butterfree')})it('should find the first string longer than 0', () => {const result = fn.firstLongerThan(['a', 'b', 'c'], 0)expect(result).toEqual('a')})it('should return undefined', () => {const result = fn.firstLongerThan([], 5)expect(result).toEqual(undefined)})})
Shape
const firstLongerThan = (arr, num) => {}
Explanation
arr and a number num.arr.find() to find the string length bigger
than num and return it.Code
const firstLongerThan = (arr, num) => {return arr.find(e => {return e.length > num})}
Write a function called getReturnValues that takes in an array of functions, and returns an array of values returned by the functions.
getReturnValues([() => {return 25},() => {return 29},() => {return 'Pikachu'}]) // returns [25, 29, "Pikachu"]
Tests
describe('getReturnValues function', () => {const fn1 = () => {return 25}const fn2 = () => {return true}const fn3 = () => {return 'Pikachu'}const fn4 = () => {"I'm function four"}it('should get 3 return values of various types', () => {const result = fn.getReturnValues([fn1, fn2, fn3])expect(result).toEqual([25, true, 'Pikachu'])})it('should return an empty array if no functions', () => {const result = fn.getReturnValues([])expect(result).toEqual([])})it('should return undefined for functions with no return value', () => {const result = fn.getReturnValues([fn4])expect(result).toEqual([undefined])})})
Shape
const getReturnValues = arr => {}
Explanation
arr.arr.map() function to go through arrays of functions.Code
const getReturnValues = arr => {return arr.map(e => {return e()})}
Write a function called zeroSquare that takes in a number, and returns a square two-dimensional array with the input number rows and columns filled with zeros.
zeroSquare(1) // returns [[0]]zeroSquare(2) // returns [[0,0], [0,0]]/*[[0,0],[0,0]]*/zeroSquare(3) // returns [[0,0,0], [0,0,0], [0,0,0]]/*[[0,0,0],[0,0,0],[0,0,0]]*/
This one won't be able to use the array helper functions we've learned so far—think recursion! Because we're dealing with a multi-dimensional array, your recursive function will need to pass around more than just one iterator or counter variable, and possibly more than one results array.
Tests
describe('zeroSquare function', () => {it('should create a 1x1 array of zeroes', () => {const square1 = [[0]]expect(fn.zeroSquare(1)).toEqual(square1)})it('should create a 1x1 array of zeroes', () => {const square2 = [[0, 0],[0, 0]]expect(fn.zeroSquare(2)).toEqual(square2)})it('should create a 1x1 array of zeroes', () => {const square3 = [[0, 0, 0],[0, 0, 0],[0, 0, 0]]expect(fn.zeroSquare(3)).toEqual(square3)})it('should return an empty array for 0 value', () => {expect(fn.zeroSquare(0)).toEqual([])})})
Shape
const makeRow = num => {}const zeroSquare = num => {}
Explanation
num.makeRow to help us make rows in the 2D array.makeRow,i ) which start at 0.res) which will start with an empty array.i equals number num,res.makeRow()zeroSquare,i ) which starts at 0.res) which will start with an empty array.i equals num,result.makeRow function and pass number num as the argument.res.const makeRow = (num, i = 0, res = []) => {if (i === num) return resres.push(0)return makeRow(num, i + 1, res)}const zeroSquare = (num, i = 0, res = []) => {if (i === num) return resres.push(makeRow(num))return zeroSquare(num, i + 1, res)}
In the last lesson, you familiarized yourself with HTML, then learned all about arrays. You'll want to have all the array functions at your disposal for this lesson, so go back and make sure you've memorized them before going forward!
If you have any issues solving any of the Preflight questions, please review the questions and solutions. This lesson will rely heavily on the foundations covered in the previous lesson in three parts:
Objects are the last, but most important, data type we'll learn in JavaScript. If the concept is new to you, remember to review frequently. After this lesson, you will have learned everything you need to solve the algorithm section of a coding interview and can start practicing the problems on leetCode. Make sure to follow the 5 steps for each problem!
In JS2 you learned about:
div tag, which we use to group elements on HTML pagesinnerHTML and innerTextIn the last lesson you learned about setting an element's onclick attribute to
assign a function to run when the user clicks on the element. A downside to this
method is that you can only assign one function to each element. Best practice
is to run the element's addEventListener function:
addEventListener('eventName', function).
Let's see how our original example from JS1 would look with an event listener:
<button class="submit1">Click Me</button><script>const button1 = document.querySelector('.submit1')button1.addEventListener('click', () => {alert("Ouch!")})</script>
The first argument, 'click', is a string event that is supported in the
browser. Other events you can add events for include mouseenter ,
mouseleave, mousemove, and keyup. These events will be covered in further
details but if you want to find out other events that the browser supports, do a
search for Browser DOM Events
If you struggled with the HTML section in JS2 ( the previous lesson ), please make sure you review / redo them again before starting this section. In the exercise section, try to come up with the steps yourself before coding!
In this section, you will learn one more element and some very important functions that allow us to work with arrays in the browser.

select allows you to build dropdown menus. The choices go inside option
elements, which are children of the select element:
<select><option>Mild</option><option>Medium</option><option>Spicy</option></select>
If we have an array of strings that we want to use for the options, we can use
reduce to generate string tags and then set the innerHTML property of the
select:
<select class="selectContainer"></select><script>const data = ['Charmander', 'Squirtle', 'Caterpie']const select = document.querySelector('.selectContainer')select.innerHTML = data.reduce((acc, e) => {return (acc +`<option>${e}</option>`)}, '')</script>
When websites send information to each other, the data is always sent and received as strings. So what do you do if you need to send an array across the Internet? You convert it to a string first!
When data (number, boolean, string, array, objects) is converted into a string, the string is called JSON. JSON stands for JavaScript Object Notation.
Databases also store data as strings, so if you want to store an array of names into the database sometimes you must convert your data to a string first.
You can turn any JavaScript data into a string with JSON.stringify.
Although JSON is primarily used for working with browsers, you can also follow along with all the below examples in node.
// Example of something that will throw error for JSON.stringifyconst a = []a.push(a) // a[0] points to itselfconst b = JSON.stringify(a)// Computer will get stuck trying to stringify a and throw error.const c = [() => {}]JSON.stringify(c)// Functions cannot be stringified.// Since c has a function inside, it cannot be stringified.
const arr = [-18, 'Charizard', true]const strArr = JSON.stringify(arr)// strArr is '[-18, "Charizard", true]'
If you used the previous function JSON.stringify to convert an array into a
string, how do you convert the string back into an array? You use the
JSON.parse function. This function takes a string and parses, or
interprets it as JavaScript data.
const arr = [-18, 'Peter Parker', true]const strArr = JSON.stringify(arr)const newArr = JSON.parse(strArr)// newArr is an array: [-18, "Peter Parker", true]const isSame = arr === newArr// is isSame true or false?
/*false because they have different addresses.Because strings are primitive,when you convert an array into a string,the address to the array is gone.When you convert a string into an array,the computer creates a new array (at a new address).*/
Let's review how all of this works.
JSON is the string that gets returned by JSON.stringify and the argument you
pass into JSON.parse.
JSON.stringify( data ) ——> JSON ——> JSON.parse(JSON) ——> data
LocalStorage lets you store data, like a database in the browser. There are many ways you can make use of LocalStorage when writing a JavaScript program, and you'll get to try a couple of examples in the next Exercise section. Here are the two key functions you'll need to know:
localStorage.setItem
localStorage.setItem is a function that takes in 2 strings.
localStorage.getItem
localStorage.getItem takes in only a string, the title of the data to
retrieve, and returns the data.
LocalStorage Example
Here's a quick UI that lets the user add text to LocalStorage. Save this as an HTML page, try storing some data, then reloading the page and storing more—you'll notice that unlike what we've used to store data so far, the LocalStorage data is persistent across page reloads. (This script logs to the console, so read this to learn how to open your browser's console.)
<input type="text" class="textBox" /><button class="submit">Store it</button><script>const submitButton = document.querySelector(".submit")const textBox = document.querySelector(".textBox")// First grab what's already in local storage.// We use || '[]' to start an array the first time// because getItem will return nullconst lsData = localStorage.getItem('mydata') || '[]'// Turn string into an arrayconst dataArray = JSON.parse(lsData)submitButton.onclick = () => {// Push the new text into itdataArray.push(textBox.value)// Store it back, turning it into a string on the waylocalStorage.setItem('mydata', JSON.stringify(dataArray))// Then console.log everything stored up till nowconsole.log(dataArray)}</script>
To clear your browser's localStorage, open your browser's devolper tools and follow these instructions:
Instead of the Storage tab, you should click on the Applications tab:
Recall how document.querySelector selects the first element it finds that
matches its argument. document.querySelectorAll is similar, except it returns
an array of all the elements that match the query.
<div><button class="hello">Hello</button><button class="hello">Hola</button><button class="hello">Bună ziua</button><button class="hello">Aloha</button><h1 class="hello">Hi World!</h1></div><script>const hellos = document.querySelectorAll('.hello')// hellos is an array of length 5:// [buttonElement, buttonElement, buttonElement, buttonElement, h1Element]const buttons = document.querySelectorAll('button')// buttons is an array of length 4:// [buttonElement, buttonElement, buttonElement, buttonElement]// To bind an onclick to each button element, simply use forEachbuttons.forEach((button, i) => {button.onclick = () => {alert(`This is the button at index ${i}`)}})</script>
Some of these UI exercises may seem intimidating. When you feel overwhelmed, take a deep breath, think about what you know, and make sure to start with that. When you work as a software engineer, you will have to handle projects that seem really intimidating. In these situations, it is important to think about what you know and understand, then slowly branch out from there piece by piece.
Good engineers spend the majority of their time thinking, not coding. Whether you are working on these exercises, interviewing for a software engineering job, or working on projects, make sure you spend the first half of your allotted time thinking through the problem before actually starting to code.
To see each page in action, click on the link. To view the solution, right-click
anywhere on the page and select View Source.
Debugging - If your page is not doing what you want it to do, you can look
at the console. This is where the browser will try to tell you what the error
is if you've written your code in a way it can't understand.
Read this to learn how to open
the browser's console.
h1 , input , button and select HTML tags and select the
elements by their class name. If you don't know what some of the tags do,
read about them at w3schools
and make sure you try them out.onclick to be a function that does the following:input tag.option tag and add to existing select element's
innerHTMLh2 element. If you click
on a todo item, it should be removed.Because you'll be keeping the todo items in an array, and changing that array whenever the user marks an item as complete, you'll have to reload the todo list each time a todo item is clicked. Removing an item changes the other items' positions in the array, so you'll also have to remake all the other items' onclick functions. Write a function that does both of these things and make sure it's called when adding or removing an item.
Examples: Try adding and removing several items from various positions on the example page (first item, last item, middle item). The other items should reorder themselves.
Function shape: As mentioned in the hint, we'll need a function to load all the todo items onto the page. This will run whenever an item is added or removed, and has no parameters or return value. The only other function is a quick one to add a new element based on user input. Here are those two, along with a simple HTML template to record and display todo items:
<h1 class="display">TODO LIST</h1><input class="newText" type="text" /><button class="add">Add</button><div class="todoList"></div><script>const list = document.querySelector('.todoList')const inputElement = document.querySelector('.newText')const buttonElement = document.querySelector('.add')const render = () => {}buttonElement.onclick = () => {}</script>
Think: We'll store the todo items in an array and then turn them into h2
elements each time the list is loaded. Each h2 should have an onclick that makes
it go away. How do we do that? We haven't learned a way to remove the element
directly, but if we remove the item from the array and then refresh the list,
that will have the same effect. We could look through the array for the string
we're removing, but what if the user had the same item in their todo list twice?
We might remove the wrong one. So we'll include each item's current position in
its onclick function. This will change every time an item is removed, but that's
OK because the onclick functions will be rewritten as well.
Code: Before any of the functions use it, we should initialize the array:
const todos = []
For the render function, there are 2 steps: turn everything into HTML and give
them their new onclick attributes. The onclick functions will need to call
render again refresh the list.
const render = () => {list.innerHTML = todos.reduce((acc, e) => {return acc + `<h2 class="todo">${e}</h2>`}, '')const todoElements = document.querySelectorAll('.todo')todoElements.forEach((e, i) => {e.onclick = () => {todos.splice(i, 1)render()}})}
All that's left is buttonElement's onclick function, which will be called when
the user inputs a new todo item. We use unshift to add to the array so that it
will start at the top of the list.
buttonElement.onclick = () => {const newValue = inputElement.valuetodos.unshift(newValue)render()}
Test: Add some items and, again, make sure that whether you remove them from the beginning, middle, or end, the other items move correctly.
Right now, our todo list is only good as long as you keep the page open. In the next part, you'll make it a lot more practical.
There are many ways to solve this. Our answer is one way that we feel is more organized. Please take the time to understand the steps.
Create a h1 , input , button and div HTML tags and select the
elements by their class name.
We need an array to hold all of the todo items, let's call it todoList
const todoList = []
Write a function called render that sets the div's innerHTML property
to a string of h1 elements from todoList array
const todoList = ['hello', 'student', 'coder']const result = render()/*div 's innerHTML will be set to:'<h1 class="todo">hello</h1><h1 class="todo">student</h1><h1 class="todo">coder</h1>'*/
Run the button's addEventListener property and pass in two arguments:
'click' and a function that:
todoListrender functionDelete: Update the render function so that after the div's innerHTML
property is updated:
.todo elementsclick event listener to each element. When element
is clicked:render functionlocalStorage.That wasn't too bad, was it? It only takes a few lines of code to implement
localStorage. When the page first loads we load existing todo items from
localStorage (using localStorage.getItem('todo') || '[]' in case there's
nothing there). But we need to update localStorage every time an item is added
or removed, because the user could close the page at any time.
render function, add localStorage.setItem to update you list in
local storage.todoList to
JSON.parse(localStorage.getItem("storedTasks") || '[]')|| '[]'so that if the localStorage is empty(user's
first time on the page), we parse an empty array string instead. So
todoList is set to an empty array.render function after you set todoList when the page loads.Part 3: Add a filter functionality: Type a few characters and click on Filter to only see todo items matching what you typed.
strings have a .includes() function that takes in a string argument and
tells you if the string exists inside the larger string.
const tropical = 'pineapple'tropical.includes('apple') // returns true because "apple" is part of "pineapple"tropical.includes('yellow') // returns false because "yellow" is not part of "pineapple"
button and input tags and select elements by their
class name.render function:todoList that has the
strings in filter inputbutton tag, next button tag, a with hr tag, add a
div to store individual stories in the UI, hr tag, textarea tag to
allow users to write their individual story, another button to submit
stories and finally a div to display all the stories.index. It starts at 0.div we created.render function which allows you to,div with all stories.render() function.button,render() and update the UI with newly added stories.button,index is 0, return alert the user that they have reached at the
beginning of the book.index by 1.div innertext to display the current index of the list.button,index has reached to the second to the last element of the list, it
returns alert notifying the user that they have reached the end of the
book.index by 1.div innertext to display the current index of the list.Create an h1 tag, two input tags for name and age, one div tag to
display name and age , and an add button. Select the elements by class
name.
Create two different arrays to store input values for name and age. Let's
call the arrays storeName and storeAge.
Create a render function. Inside this function,
Attach reduce method to the array storeName.
age inside the reduce method and set it current
index of array storeAge.Set the innerHTML of div to :
<div><h2 class="displayName">${e}</h2><h3 class="displayAge">${age}</h3></div>
If you are having hard time figuring out where e is coming from in the
code, then please review the array method reduce and how it works.
Attach addEventListener to add button. It takes in two arguments.
"click" as the first argument.storeName and storeAge arrays.render function.JSON.parse both arrays that you have stored in the localStorage.render function.render function to do:storeAge in the UI.h2 element by its class name. (This h2 element was created
in the first part of this exercise.)onclick method to each h2 element. This onclick will run the
alert function which will display the age.localStorage.setItem to store the updated arrays inside the event
listener for the add button.