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

© 2023. All rights reserved.