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
Challenge a Friend
Send this duel to someone else and see if they can solve it.