This folder contains JavaScript exercises focused on working with arrays β including adding, removing, selecting, and displaying items. These labs practice real-world array operations, state management, and basic safety checks.
More array-focused practice labs will be added here as I continue learning.
This exercise simulates managing a lunch menu using an array. The program allows items to be added or removed from both the beginning and end of the menu, randomly selects an item, and displays the current menu contents.
"Tacos" added to the end of the lunch menu.
"Sushi" added to the start of the lunch menu.
"Burger" removed from the end of the lunch menu.
Randomly selected lunch: Pizza
Menu items: Soup, Tacos, Pizza
push() and unshift()pop() and shift()Math.random()join()This lab reinforced how arrays can be used to manage collections of data that change over time. It also emphasized the importance of handling empty arrays safely and writing clear, readable functions that modify shared state in predictable ways.
This exercise builds a function that accepts an array of arrays and returns a new array containing the largest number from each sub-array.
largestOfAll([[1, 2, 3], [4, 5], [9, 0]]) β [3, 5, 9]
Math.max()This lab reinforced how to work with nested arrays and extract meaningful values from each sub-collection. It highlighted how built-in utilities like Math.max() can simplify logic when combined with array traversal, while still keeping the core problem focused on data structure manipulation.
This exercise builds a function that inserts the elements of one array into another array at a specified index, returning a new array without modifying either source array.
frankenSplice([1, 2], ["a", "b"], 1) β ["a", 1, 2, "b"]
splice() for controlled insertionThis lab reinforced the importance of preserving original data when combining arrays. It highlighted how array methods like splice() can be safely used when operating on copies, and how careful index management ensures elements are inserted in the correct order.
This exercise filters an input array and returns a new array containing only truthy values. Any values that evaluate to false in a Boolean context are removed.
The solution manually iterates through the array, checks each valueβs truthiness, and builds a new array with only valid entries.
bouncer([7, 'ate', '', false, 9]) β [7, 'ate', 9]
bouncer([false, null, 0, NaN, undefined, '']) β []
bouncer([null, NaN, 1, 2, undefined]) β [1, 2]
This lab introduced a core data-processing pattern: scan, test, and keep/discard. It reinforced how JavaScript evaluates values in Boolean contexts and how arrays can be filtered using conditional logic. This exercise serves as a foundational step toward more advanced array methods like .filter(), which automate this pattern in modern JavaScript.
This exercise merges multiple arrays into a single array that contains only unique values, while preserving the order in which values first appear.
The solution manually iterates through each input array and builds a new array by adding values only if they have not already been included.
uniteUnique([1, 3, 2], [5, 2, 1, 4], [2, 1]) β [1, 3, 2, 5, 4]
uniteUnique([1, 2, 3], [5, 2, 1]) β [1, 2, 3, 5]
uniteUnique(['a', 1, true], [1, 'a', false]) β ['a', 1, true, false]
.includes()This lab reinforced a fundamental array-processing pattern: scan, check, and append. It also highlighted how JavaScript determines value equality, which is especially important when working with mixed data types. The approach taken here mirrors how higher-level tools like Set can be used for deduplication, but implementing it manually helps build a deeper understanding of how uniqueness is enforced step-by-step.
This exercise builds DNA base pairs from an input string of DNA bases. Each character in the string is paired with its complementary base according to biological pairing rules.
The function processes the sequence character by character and returns a two-dimensional array representing the paired structure.
pairElement("ATCGA") β [["A","T"],["T","A"],["C","G"],["G","C"],["A","T"]]
pairElement("ttgag") β [["T","A"],["T","A"],["G","C"],["A","T"],["G","C"]]
This lab introduces structured data construction by transforming a simple string into a two-dimensional array. It reinforces how rule-based logic can be used to map individual values into related pairs, and demonstrates how nested data structures are created programmatically. The exercise also highlights the importance of normalizing input before processing.
This exercise removes elements from the beginning of an array until a specified condition is satisfied. The function uses a callback to test each element and returns the remaining portion of the array starting from the first element that passes the test.
dropElements([1, 2, 3, 4], n => n >= 3) β [3, 4]
dropElements([0, 1, 0, 1], n => n === 1) β [1, 0, 1]
dropElements([1, 2, 3, 4], n => n > 5) β []
.slice()This lab demonstrates how higher-order functions can influence control flow within array processing. It reinforces the concept of using callback functions to determine behavior dynamically and shows how array slicing can be used to efficiently return a portion of data based on a condition. The exercise also highlights the usefulness of early returns in simplifying logic.
This lab works with an array of book objects to extract, filter, and aggregate information about a small library catalog. The functions transform structured data into readable lists, targeted results, and summary statistics.
getBookInformation(library) β "Atomic Habits by James Clear\n..."
getBooksByAuthor(library, "Arvid Kahl")
β [{ title: "The Embedded Entrepreneur", ... }, { title: "Zero to Sold", ... }]
getTotalPages(library) β 2512
.map().filter().reduce()This lab reinforces how arrays of objects are manipulated in real-world JavaScript. Instead of working with simple numbers or strings, the data now contains multiple properties per item, requiring precise selection and transformation. The exercise demonstrates how array methods can be combined to extract meaningful insights (lists, subsets, totals) from structured datasets, mirroring common data-processing tasks in applications.
This lab filters and sorts an array of book objects based on release year. It demonstrates how multiple array methods can be combined to extract a meaningful subset of data and then order it deterministically.
filteredBooks.length β 10
filteredBooks[0].title β "The Wizard's First Rule"
filteredBooks[filteredBooks.length - 1].title β "Naked Empire"
.filter()This lab reinforces how array methods can be chained together to transform structured data into a curated result set. Instead of manipulating individual values, the logic operates on objects with multiple properties, requiring deliberate comparison rules. The exercise highlights how filtering reduces a dataset to relevant entries, while sorting imposes predictable orderβboth common operations in real-world applications.
This lab determines the correct index where a number should be inserted into an array after the array is sorted numerically. The function ensures the insertion point preserves ascending order.
getIndexToIns([10, 20, 30, 40, 50], 35) β 3
getIndexToIns([3, 10, 5], 11) β 3
getIndexToIns([], 5) β 0
.findIndex() to locate insertion points.sort()This lab demonstrates how ordering logic and index detection work together when managing sorted data. Instead of simply modifying values, the function evaluates where a new value belongs relative to existing elements. It reinforces how built-in array methods can be combined to produce deterministic positioning β a common requirement in data processing and algorithmic tasks.
This lab compares two arrays and returns the values that appear in only one of them. It demonstrates how filtering and membership checks can be combined to identify unique elements between datasets.
diffArray(['pen', 'book'], ['book', 'pencil', 'notebook']) β ["pen", "pencil", "notebook"]
diffArray(['apple', 'banana'], []) β ["apple", "banana"]
diffArray([], []) β []
.includes() for value comparisonThis lab reinforces how comparison logic can be applied across collections of data. Rather than transforming individual elements, the function evaluates relationships between two datasets to determine which values are exclusive to each. This mirrors real-world tasks like data reconciliation, change detection, and difference analysis.
This lab removes specific values from an array using additional arguments supplied to the function. It demonstrates how rest parameters and filtering logic work together to eliminate unwanted elements.
destroyer([1, 2, 3, 5, 1, 2, 3], 2, 3) β [1, 5, 1]
destroyer(['tree', 'hamburger', 53], 'tree', 53) β ["hamburger"]
destroyer([2, 3, 2, 3], 2, 3) β []
.includes()This lab reinforces how JavaScript functions can accept dynamic numbers of arguments and apply them as filtering criteria. Instead of transforming values, the function evaluates which elements should be removed based on a comparison set. This mirrors common real-world tasks such as data cleanup, blacklist filtering, and rule-based exclusion.
These labs focused on core array operations used in real applications β managing changing collections, extracting values from nested data, and combining arrays safely. Together, they reinforced the difference between mutating and non-mutating approaches and built confidence working with arrays as a primary data structure.