JavaScript Practice: Progressive Coding Challenges with Test Cases

Developer testing progressive JavaScript exercises on a laptop

Build JavaScript practice through eight focused problems that increase in difficulty. Each exercise defines an input, required output, constraints, sample cases, and review criteria, so you can test behavior instead of relying on an open-ended project brief.

Start with the first section, then move forward only when your implementation passes the listed edge cases. These JavaScript coding challenges are short enough for repeated attempts and code reviews.

JavaScript Practice: Beginner String and Number Challenges

Reverse a string

Input: A string. Required output: The characters in reverse order. Constraints: Preserve every character, including spaces, and support empty input. Samples: "JavaScript" → "tpircSavaJ"; "" → "". Hint: Use a loop or reverse and join. Review: Check that no characters are lost and the source value is not mutated.

Count vowels

Input: A string. Required output: The number of a, e, i, o, and u characters. Constraints: Count case-insensitively and ignore nonletters. Samples: "JavaScript" → 3; "rhythm!" → 0. Hint: Normalize the string and use a vowel lookup. Review: Empty input must return 0, and uppercase vowels must count.

Build FizzBuzz

Input: A positive integer n. Required output: An array from 1 through n, replacing multiples of 3 with "Fizz", multiples of 5 with "Buzz", and multiples of both with "FizzBuzz". Constraints: 1 ≤ n ≤ 1,000. Samples: 5 → [1, 2, "Fizz", 4, "Buzz"]; 15 → [1, 2, "Fizz", 4, "Buzz", "Fizz", 7, 8, "Fizz", "Buzz", 11, "Fizz", 13, 14, "FizzBuzz"]. Hint: Test divisibility by 15 first. Review: Preserve order and the number-versus-string value types.

JavaScript Coding Challenges for Arrays and Objects

Keep first occurrences

Input: An integer array. Required output: A unique array preserving first-seen order. Constraints: Do not sort the values or change the source array. Samples: [3, 1, 3, 2, 1] → [3, 1, 2]; [] → []. Hint: Track seen values with a Set or lookup. Review: Test duplicates at the beginning, middle, and end, and verify the original array remains unchanged.

Group records

Input: An array of objects with name and team properties. Required output: An object mapping each team to an array of names. Constraints: Preserve input order and create no empty groups. Sample: [{name: "Ana", team: "red"}, {name: "Bo", team: "blue"}, {name: "Cy", team: "red"}] → {red: ["Ana", "Cy"], blue: ["Bo"]}. Hint: Build an accumulator as you iterate. Review: Check exact keys, name order, and behavior with an empty array.

JavaScript Code Challenges for Functions and Data Transformation

Compose unary functions

Input: A list of synchronous unary functions and a value x. Required output: The result after applying functions from left to right. Constraints: Functions accept and return one value. Samples: [x=>x+2, x=>x*3], 4 → 18; [], 4 → 4. Hint: Reduce over the function list. Review: Confirm execution order and avoid mutating the list.

Summarize a cart

Input: An array of {price, qty} items and a tax rate. Required output: The total after tax, rounded to two decimals. Constraints: Prices, quantities, and tax are nonnegative; apply tax after calculating the subtotal. Samples: [{price: 10, qty: 2}], 0.1 → 22; [], 0.2 → 0. Hint: Reduce the subtotal before rounding. Review: Prevent string concatenation, handle zero items, and account for floating-point rounding.

Async Extension: Reliable Fetch Behavior

Retry an async request

Input: A promise factory and a maximum-attempts integer. Required output: The first resolved value, or the final rejection after all attempts fail. Constraints: Call the factory once per attempt, require maxAttempts ≥ 1, and stop immediately after success. Samples: A factory yielding Error("E1"), Error("E2"), then "ok" with 3 attempts resolves to "ok" on call 3; two failures with maxAttempts=2 reject Error("E2"). Hint: Use an await loop with try/catch. Review: Preserve the final error and verify the exact attempt count.