DEV Community

Cover image for Top 30 Javascript Interview Warmup Exercises Part 2
Theofanis Despoudis
Theofanis Despoudis

Posted on • Updated on • Originally published at codethat.today

Top 30 Javascript Interview Warmup Exercises Part 2

Read the original in CodeThat.today

Welcome back. Here is the second part of the series about the top 30 Javascript Interview Warmup Exercises. If you are going to attend an interview that will ask algorithmic questions in Javascript then this list should be bookmarked for reference.

Let's get started.

Questions 🤔

  • 1. Write a function that accepts a number and checks if it's a prime or not.

To check if a number n is prime we need to go through the list of numbers i from 2 up until n/2 and check if n equally divides this number i. This is to ensure that we cannot express n as a factor of i.

Here is the gist of the code:

function isPrime(n) { if (n === 1) { // Special case for 1 return false; } else { // Go through all numbers from 2 up until n/2 for (let i = 2; i <= n / 2; i += 1) { if (n % i === 0) { // We found a number i such as i * x = n so the number is not prime return false; } } // If we got to this point then we know the number is prime return true; } } let num = 45; console.info("Is " + num + " a prime?: " + isPrime(num)); num = 37; console.info("Is " + num + " a prime?: " + isPrime(num)); num = 73; console.info("Is " + num + " a prime?: " + isPrime(num));
  • 2. Write a function that accepts a list of objects with the following type structure:
{
   id: number,
   accountType: "user" | "admin" | "root"
   name: string
}

Enter fullscreen mode Exit fullscreen mode

The function should return the list of objects grouped by their accountType in this order. For example it should return a list with a list of user followed by a list of admin and a list of root accounts.

In order to group by the account type we need to store them in a way that the key is the accountType value (user, admin or root) and the value is the list of records with that accountType. We can use a map and just iterate over the those keys and update the collection every-time we match a value.

Then to return the results in a custom order we just combine the results for each type of accountType in an array.

Here is the gist of the code:

// Somewhat generic group function function groupBy(records, keyFunc) { // Save groups by key here. const groups = new Map(); for (record of records) { // We need this call to retrieve the actual key const key = keyFunc(record); if (groups.has(key)) { const data = groups.get(key); data.push(record); } else { groups.set(key, [record]); } } return groups; } function getGroupsByAccountType (records) { const groups = groupBy(records,function(record) { return record.accountType; }); // Return by custom ordering here return [ ...groups.get('user'), ...groups.get('admin'), ...groups.get('root'), ] } console.info(getGroupsByAccountType([ { id: 1, accountType: 'user', name: 'Mike' }, { id: 2, accountType: 'admin', name: 'Alex' }, { id: 3, accountType: 'root', name: 'Jordan' }, { id: 4, accountType: 'user', name: 'Silas' }, { id: 5, accountType: 'admin', name: 'John' }, ]))
  • 3. Write a function that accepts a DOM element and a string and prints any of it's immediate children that contain the class name with that string.

Using the DOM API we can request the NodeList of the current element children using the childNodes property. Then we can iterate this list and check the class value using the getAttribute("class") or the classList property for the specified class name.

Here is the gist of the code:

Given the following DOM for example:

<ul id="list">
    <li class="even"><a href="#Syntax" rel="internal">Syntax</a></li>
    <li class="odd"><a href="#Examples" rel="internal">Examples</a></li>
    <li class="even"><a href="#Polyfill" rel="internal">Polyfill</a></li>
    <li class="odd"><a href="#Specifications" rel="internal">Specifications</a></li>
    <li class="even"><a href="#Browser_compatibility" rel="internal">Browser compatibility</a></li>
    <li class="even"><a href="#See_also" rel="internal">See also</a></li>
</ul>
Enter fullscreen mode Exit fullscreen mode

The code for printing the children nodes with a target className is:

function printChildrenContainingClass(rootElement, className) {
  if (rootElement) {
    // Iterate over the childNodes
    list.childNodes.forEach((node) => {
      // If a childnode contains a className print the node
      if (node.classList.contains(className)) {
        console.info(node);
      }
    });
  }
}

printChildrenContainingClass(document.querySelector('#list'), 'odd'));
Enter fullscreen mode Exit fullscreen mode
  • 4. Write a function that accepts a DOM element and a string and prints if any of its parent nodes contains the class with that string. It should stop when there are no parent elements.

Here we can use the parentNode property to get the current element parent Node. Then we will check if the parent has a class with that name. If not we will recursively get the parent of that node again until we reach the Document Node or a node that has no parent:

Here is the gist of the code:

Given the following DOM for example:

<body>
    <aside class="sidebar">
        <ul id="list" class="sidebar-list">
            <li class="even"><a href="#Syntax" rel="internal">Syntax</a></li>
            <li class="odd"><a href="#Examples" rel="internal">Examples</a></li>
            <li class="even"><a href="#Polyfill" rel="internal">Polyfill</a></li>
            <li class="odd"><a href="#Specifications" rel="internal">Specifications</a></li>
            <li class="even"><a id="start" href="#Browser_compatibility" rel="internal">Browser compatibility</a></li>
            <li class="even"><a href="#See_also" rel="internal">See also</a></li>
        </ul>
    </aside>
</body>
Enter fullscreen mode Exit fullscreen mode

The code for printing the parent nodes with a target className is:


function printParentsContainingClass(childElement, className) {
  if (childElement) {
    // Iterate over the parentNodes
    let parentNode = childElement.parentNode;
    while (parentNode !== null) {
      // If a parentNode contains a className print the node
      if (parentNode.classList && parentNode.classList.contains(className)) {
        console.info(parentNode);
      }
      // Go up
      parentNode = parentNode.parentNode;
    }
  }
}

printParentsContainingClass(document.getElementById('start'), 'sidebar');

Enter fullscreen mode Exit fullscreen mode
  • 5. Given the following DOM structure:
<ul id="list-start">
   <li>Theo</li>
   <li>Alex</li>
   <li>Mike</li>
</ul>
Enter fullscreen mode Exit fullscreen mode

Write relevant Javascript code so that when we click any of the list elements the following alert will display in the browser:

<name> was clicked where <name> is the element clicked. How can you make it work with only one event listener?

We could add individual event listeners here one for each <li> element but we can do better by using one in the parent node <ul>. The idea is to leverage event propagation and bubbling so that when we click anywhere within the <ul> area we would pick the current target text node and show the alert message.

Here is the gist of the code:

function onListElementClicked(event) {
  if(event.target && event.target.nodeName == "LI") {
    // List item found. Alert the innerText
    alert(event.target.innerText +  " was clicked");
  }
}

let list = document.getElementById('list-start');
if (list) {
  list.addEventListener('click', onListElementClicked);
}
Enter fullscreen mode Exit fullscreen mode
  • 6. Write a function that checks if a given string is a palindrome.

By definition, a string is a palindrome if it read backwards the same. For example the following strings are palindrome:

"aba", "assissa"

However the following strings are not palindrome:

"abc", "asibisaa"

We can check if a string is a palindrome using a for loop over two indexes. The first index start at the start of the string and the second index starts at the end and moves towards the start. If at any time the characters at S[i] !== S[j] then we found a mismatch so the string is not a palindrome. We stop when we've reached the middle of the string.

Here is the gist of the code:

function isPalindrome(inputStr) { let lo = 0; let hi = inputStr.length; let mid = Math.floor((lo + hi) / 2); // Check until the mid element for (let i = 0, j = hi-1; i < mid; i += 1, j -= 1) { if (inputStr[i] !== inputStr[j]) { return false; } } // If we got in here then we know that the string is palindrome return true; } console.info(isPalindrome("ab")) console.info(isPalindrome("a")) console.info(isPalindrome("aba")) console.info(isPalindrome("abc")) console.info(isPalindrome("abba"))
  • 7. Write a function to represents a linked list.

A lot of times you are asked to implement something in a linked list such as reverse a list or find any cycles. So it's important to be able to implement one on the fly. Here is a simple implementation with a few basic operations:

// Node holds the data and a reference to the next node function LinkListNode(data) { this.data = data; this.next = null; } // Linked list Basic Structure function LinkedList() { this.len = 0; this.head = null; } // Operations LinkedList.prototype.push = function(item) { if (item) { let node = new LinkListNode(item); // if the current head is null we set item as head and update the length if (!this.head) { this.head = node; this.len += 1; return node; } // Otherwise we follow the next links until we reach the end of the list let currentNode = this.head; while (currentNode.next !== null) { currentNode = currentNode.next; } // If we got here then we have reached the end. currentNode points to the last element currentNode.next = node; this.len += 1; return node; } }; LinkedList.prototype.head = function() { return this.head; }; LinkedList.prototype.length = function() { return this.len; }; let list = new LinkedList(); list.push(1); list.push(2); list.push(3); list.push(4); console.info('List is: '); let currentNode = list.head while(currentNode !== null) { console.info(currentNode.data); currentNode = currentNode.next; }
  • 8. Write a function to represents a Stack.

A lot of times you are asked to implement an algorithm that uses a Stack such as DFS traversal or checking if an expression is balanced. So it's important to be able to implement one on the fly. Here is a simple implementation with a few basic operations:

function Stack() { this.items = []; } // Operations Stack.prototype.push = function(item) { this.items.push(item); } Stack.prototype.pop = function() { return this.items.pop(); } Stack.prototype.top = function() { return this.items[this.items.length - 1]; } Stack.prototype.isEmpty = function() { return this.items.length === 0; } let stack = new Stack(); stack.push(1); stack.push(2); stack.push(3); stack.push(4); console.info('Stack is: ', ); while(!stack.isEmpty()) { console.info(stack.pop()); }
  • 9. Write code that represents a Queue data structure.

A lot of times you are asked to implement an algorithm that uses a Queue such as BFS traversal. So it's important to be able to implement one on the fly. Here is a simple implementation with a few basic operations:

function Queue() { this.items = []; } Queue.prototype.enqueue = function(item) { this.items.push(item); } Queue.prototype.dequeue = function() { return this.items.shift(); } Queue.prototype.top = function() { if (this.items.length > 0) { return this.items[0]; } return null; } Queue.prototype.isEmpty = function() { return this.items.length === 0; } let q = new Queue(); q.enqueue(1); q.enqueue(2); q.enqueue(3); q.enqueue(4); console.info('Queue is: ', ); while(!q.isEmpty()) { console.info(q.dequeue()); }
  • 10. Write code that represents a graph data structure.

A lot of times you are asked to implement an algorithm that uses a Graph DTS such as finding shortest paths. So it's important to be able to implement one on the fly. Here is a simple implementation with a few basic operations:

function Graph() { this.vertices = new Map(); this.edges = []; } Graph.prototype.addVertex = function(vertex) { this.vertices.set(vertex, vertex); this.edges[vertex] = []; }; Graph.prototype.addEdge = function(from, to) { this.edges[from].push(to); this.edges[to].push(from); }; Graph.prototype.size = function() { return this.vertices.size; }; Graph.prototype.removeVertex = function(vertex) { // Check if vertex exists if (this.vertices.has(vertex)) { this.vertices.delete(vertex); // Find all relevant edges and delete them while (this.edges[vertex].length > 0) { let linkedVertex = this.edges[vertex].pop(); // Remove all edges pointing to this vertex. this.removeEdge(linkedVertex, vertex); } } }; Graph.prototype.removeEdge = function(from, to) { // Find all references of from edges and remove them let firstIndex = this.edges[from] ? this.edges[from].indexOf(to) : -1; // Find all references of to edges and remove them let secondIndex = this.edges[to] ? this.edges[to].indexOf(from) : -1; if (firstIndex !== -1) { this.edges[from].splice(firstIndex, 1); } if (secondIndex !== -1) { this.edges[to].splice(secondIndex, 1); } }; let graph = new Graph(); graph.addVertex(1); graph.addVertex(2); graph.addVertex(3); graph.addVertex(4); graph.addEdge(1, 2); graph.addEdge(1, 3); graph.addEdge(2, 3); graph.addEdge(2, 4); graph.addEdge(3, 4); graph.removeVertex(2); console.info(graph);

What's next

Stay put for the next part!

😉👌💖

Interested in Mentoring or Training?

Contact me via www.techway.io for more information.

Top comments (3)

Collapse
 
q3flat profile image
q3flat

If you want to check whether is a number prime or not, you just have to go up to sqrt(n).

Collapse
 
1baga profile image
1baga

Please kindly explain

Collapse
 
cyuste profile image
Info Comment hidden by post author - thread only accessible via permalink
cyuste

I think that in the first exercise it should be better to make a special case 2 too and then iterate from 3 incrementing 2 by 2. It shows that you don't only know how to code but basic math too ;)

Some comments have been hidden by the post's author - find out more