Functional Programming in JavaScript: Refactoring User List Processing
This article demonstrates how to apply functional programming concepts in JavaScript by refactoring an example that reads user data from an API, filters active SREs, and formats output, illustrating the benefits of pure functions, higher‑order utilities like map, filter, reduce, and improved code readability and maintainability.
The article introduces a real‑world scenario where a developer needs to fetch a list of users from an HTTP endpoint, filter those who are currently working and have the role "SRE", and output their names, emails, phone numbers, and associated project groups.
Initially the implementation uses a long Promise callback with mutable state, nested loops, and side‑effects, which leads to poor readability, reusability, testability, and maintainability.
To address these issues, the author explains core functional programming ideas—treating functions as first‑class citizens, avoiding mutable state, and writing pure functions whose output depends only on their inputs.
Key functional utilities such as map , filter , and reduce are introduced and applied to the problem. For example, extracting all Chinese names can be written as:
const userChNames = users.map(u => u.ch_name);Filtering SRE users becomes:
const sreUsers = users.filter(u => u.groups.some(g => g.role === 'sre'));Counting SREs with reduce :
const sreNum = users.reduce((acc, u) => isSre(u) ? acc + 1 : acc, 0);The refactored code is split into small, pure functions: fetching data ( fetchUsers ), printing results ( printResult ), extracting working users, extracting SRE users, getting a user's formatted string, and composing the final output. The main flow simply awaits the data, processes it, and prints the result.
import Axios from 'axios';
async function fetchUsers() {
const url = 'http://xxx.163.com/api/v1/users';
try {
const result = await Axios.get(url);
return result.data;
} catch (err) {
console.error(err);
return [];
}
}
function getWorkingUsers(users) {
return users.filter(u => u.status === 'working');
}
function getSreUsers(users) {
return users.filter(u => u.groups.some(g => g.role === 'sre'));
}
function getUserInfoStr(user) {
const groupsInfo = user.groups
.filter(g => g.role === 'sre')
.map(g => `${g.ch_name}(${g.code})`)
.join(',');
return `${user.ch_name} (${user.email}) ${user.phone}: ${groupsInfo}`;
}
function processUsers(users) {
const workingSre = getSreUsers(getWorkingUsers(users));
const header = workingSre.map(u => u.ch_name).join('、');
const details = workingSre.map(getUserInfoStr).join('\n');
return `目前值班SRE: ${header}\n\n${details}`;
}
async function main() {
const users = await fetchUsers();
const result = processUsers(users);
console.log(result);
}
main();The author also discusses higher‑order functions that generate predicates (e.g., ifUserAtStatus(status) ) and attribute extractors, showing how they can further abstract filtering logic.
Finally, the article notes that while functional techniques improve clarity and testability, they should be used judiciously; over‑use may hurt readability, and performance considerations (for‑loops vs. map/filter) are secondary to maintainability in most front‑end projects.
NetEase Game Operations Platform
The NetEase Game Automated Operations Platform delivers stable services for thousands of NetEase titles, focusing on efficient ops workflows, intelligent monitoring, and virtualization.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.