Array.reduce
A collection of exercises to help solidify my understanding of the Array array.reduce() method. The questions are of varying difficulty.
1. Use .reduce to split an array of numbers into evens and odds.
const nums = [1, 2, 3, 4, 5, 6]; // Input
{ even: [2, 4, 6], Iodd: [1, 3, 5] } // Expected Output
Solution:
const result = nums.reduce((res, num) => {
if (num % 2 === 0) {
res["even"] = res["even"] ? [...res["even"], num] : [num];
} else {
res["odd"] = res["odd"] ? [...res["odd"], num] : [num];
}
return res;
}, {});
2. Find the longest word in an array
const words = ["apple", "banana", "pear", "watermelon"]; // Input
("watermelon"); // Expected Output:
Solution:
const longestWord = words.reduce(
(acc, word) => (word.length > acc.length ? word : acc),
""
);
3. Flatten an array of arrays
// input
const nested = [[1, 2], [3, 4], [5]]; // Input
[1, 2, 3, 4, 5]; // Expected output
Solution:
const flat = nested.reduce((acc, item) => [...acc, ...item], []);
4. Group objects by category
// Input
const products = [
{ name: "Shirt", category: "Clothing" },
{ name: "Pants", category: "Clothing" },
{ name: "Apple", category: "Food" },
{ name: "Banana", category: "Food" },
];
// Expected Output
{
Clothing: ["Shirt", "Pants"],
Food: ["Apple", "Banana"]
}
Solution:
const groupedProducts = products.reduce((acc, product) => {
acc[product.category] = acc[product.category]
? [...acc[product.category], product.name]
: [product.name];
return acc;
}, {});
5. Find the person with the highest score
// Input
const people = [
{ name: "Alice", score: 42 },
{ name: "Bob", score: 88 },
{ name: "Charlie", score: 75 },
];
// Expected Output
{ name: "Bob", score: 88 }
Solution:
const topPerson = people.reduce(
(acc, person) => (person.score > (acc["score"] || 0) ? person : acc),
{}
);
6. Transform array of objects into an object keyed by ID
// Input
const users = [
{ id: 1, name: "Alice" },
{ id: 2, name: "Bob" },
];
// Expected Output
{
1: { id: 1, name: "Alice" },
2: { id: 2, name: "Bob" }
}
Solution:
const keyedObject = users.reduce((acc, user) => {
acc[user.id] = acc[user.id] ? { ...acc[user.id], ...user } : { ...user };
return acc;
}, {});
7. Create a frequency map of characters in a string
const str = "hello world"; //Input
{ h: 1, e: 1, l: 3, o: 2, " ": 1, w: 1, r: 1, d: 1 } // Expected Output
Solution:
const fMap = str.split("").reduce((acc, s) => {
acc[s] = (acc[s] || 0) + 1;
return acc;
}, {});
8. Merge multiple objects into one
const objs = [{ a: 1 }, { b: 2 }, { c: 3, a: 5 }]; // Input
{ a: 5, b: 2, c: 3 } // Expected output
Solution:
const obj = objs.reduce((acc, o) => ({ ...acc, ...o }), {});
9. Find the average age
// Input
const people = [
{ name: "Alice", age: 20 },
{ name: "Bob", age: 30 },
{ name: "Charlie", age: 25 },
];
// Expected Output
25;
Solution:
const averageAge = people.reduce((acc, p) => acc + p.age, 0) / people.length;
10. Build an index of words with their positions
const text = ["hello", "world", "hello"]; // Input
// expected Output
{
hello: [0, 2],
world: [1]
}
Solution:
const wordIndex = text.reduce((acc, word, i) => {
acc[word] = acc[word] ? [...acc[word], i] : [i];
return acc;
}, {});
11. Convert CSV-like data into an array of objects
// input
const headers = ["id", "name", "age"];
const rows = [
[1, "Alice", 25],
[2, "Bob", 30],
[3, "Charlie", 28],
];
// output
[
{ id: 1, name: "Alice", age: 25 },
{ id: 2, name: "Bob", age: 30 },
{ id: 3, name: "Charlie", age: 28 },
];
Solution:
const data = rows.reduce((acc, row) => {
const rowObj = row.reduce((rowAcc, rowCurr, index) => {
rowAcc[headers[index]] = rowCur;
return rowAcc;
}, {});
return [...acc, rowObj];
}, []);
This one was a bit tricky, Ended up nesting .reduce function to get required output.
12: Group sales by region and sum their totals
// input
const sales = [
{ region: "East", amount: 100 },
{ region: "West", amount: 200 },
{ region: "East", amount: 50 },
{ region: "West", amount: 150 },
{ region: "North", amount: 75 },
];
// expected output
{
East: 150,
West: 350,
North: 75
}
Solution:
const agg = sales.reduce((acc, sale) => {
acc[sale.region] = (acc[sale.region] || 0) + sale.amount;
return acc;
}, {});
13. Transform employee data into a department-wise salary report
// Input
const employees = [
{ name: "Alice", dept: "HR", salary: 5000 },
{ name: "Bob", dept: "IT", salary: 7000 },
{ name: "Charlie", dept: "HR", salary: 6000 },
{ name: "Dave", dept: "IT", salary: 8000 }
];
// Expected Output
{
HR: { total: 11000, employees: ["Alice", "Charlie"] },
IT: { total: 15000, employees: ["Bob", "Dave"] }
}
Solution:
const aggregate = employees.reduce((acc, employee) => {
if (acc[employee.dept]) {
acc[employee.dept].total += employee.salary;
acc[employee.dept].employee.push(employee.name);
} else {
acc[employee.dept] = { total: employee.salary, employees: [employee.name] };
}
return acc;
}, {});
14. Create a histogram of word lengths
// Input
const words = ["hi", "hello", "world", "yes", "no", "maybe"];
// Expected Output
{
2: ["hi", "no"],
3: ["yes"],
5: ["hello", "world"],
5: ["maybe"]
}
Solution:
const histogram = words.reduce((acc, word) => {
const l = word.length;
acc[l] = acc[l] ? [...acc[l], word] : [word];
return acc;
}, {});
15. Build a nested category tree
// Input
const items = [
{ category: "Fruit", sub: "Citrus", name: "Orange" },
{ category: "Fruit", sub: "Citrus", name: "Lemon" },
{ category: "Fruit", sub: "Berries", name: "Strawberry" },
{ category: "Vegetable", sub: "Root", name: "Carrot" },
];
// Expected Output
{
Fruit: {
Citrus: ["Orange", "Lemon"],
Berries: ["Strawberry"]
},
Vegetable: {
Root: ["Carrot"]
}
}
Solution:
const nestedItems = items.reduce((acc, item) => {
const cat = item.category;
const sub = item.sub;
if (!acc[cat]) {
acc[cat] = {};
}
acc[cat][sub] = acc[cat][sub] ? [...acc[cat][sub], item.name] : [item.name];
return acc;
}, {}); 1,079 words