javascriptadvanced15 minutes

Refactor and Optimize Deeply Nested Array and Object Processing in JavaScript

Improve the readability, maintainability, and performance of a complex function that processes deeply nested arrays and objects without changing its behavior.

Challenge prompt

You are given a function that processes an array of user data objects containing nested properties for user activities, preferences, and metadata. The function is currently deeply nested, hard to read, and inefficient. Your task is to refactor this function to improve code clarity, reduce nesting depth, remove redundant computations, and optimize performance, while ensuring it produces the exact same output for any input. The function aggregates and returns a summary report object including counts, filtered data arrays, and derived metrics.

Guidance

  • Break down large blocks of nested conditionals into smaller, reusable helper functions.
  • Use early returns to decrease nesting and improve clarity.
  • Avoid unnecessary iterations or recalculations by caching interim results.
  • Use modern JavaScript features such as destructuring, map(), filter(), and reduce() for cleaner data transformations.

Hints

  • Extract complex conditional checks and data transformations into well-named functions.
  • Leverage Array.prototype.reduce() to accumulate results efficiently without multiple passes.
  • Consider immutability and avoid side effects to keep logic predictable and easier to test.

Starter code

function generateUserReport(users) {
  const report = { activeUsers: 0, premiumUsers: 0, recentLogins: [], preferencesSummary: {} };
  for (let i = 0; i < users.length; i++) {
    const user = users[i];
    if (user && user.profile) {
      if (user.status === 'active') {
        report.activeUsers++;
      }
      if (user.subscription && user.subscription.type === 'premium') {
        report.premiumUsers++;
      }
      if (user.activity && user.activity.loginDates) {
        for (let j = 0; j < user.activity.loginDates.length; j++) {
          const loginDate = user.activity.loginDates[j];
          if (new Date(loginDate) > new Date(Date.now() - 7 * 24 * 60 * 60 * 1000)) {
            report.recentLogins.push(user.id);
            break;
          }
        }
      }
      if (user.preferences) {
        for (const key in user.preferences) {
          if (user.preferences.hasOwnProperty(key)) {
            if (!report.preferencesSummary[key]) {
              report.preferencesSummary[key] = new Set();
            }
            report.preferencesSummary[key].add(user.preferences[key]);
          }
        }
      }
    }
  }
  for (const key in report.preferencesSummary) {
    if (report.preferencesSummary.hasOwnProperty(key)) {
      report.preferencesSummary[key] = Array.from(report.preferencesSummary[key]);
    }
  }
  return report;
}

Expected output

For an input array users, the output will be an object with these properties: activeUsers (number), premiumUsers (number), recentLogins (array of user IDs who logged in within last 7 days), and preferencesSummary (object mapping preference keys to arrays of unique values).

Core concepts

code refactoringarray iteration and transformationnested object handlingperformance optimization

Challenge a Friend

Send this duel to someone else and see if they can solve it.