如何使用高阶函数从邮箱数组生成免费域名邮箱计数对象?
问题描述
需要实现并默认导出一个函数getFreeDomainsCount,函数接收邮箱列表作为输入,返回各免费域名对应的邮箱数量,免费域名列表存储在常量freeEmailDomains中。
示例输入输出
const emails = [ 'info@gmail.com', 'info@yandex.ru', 'info@hotmail.com', 'mk@host.com', 'support@hexlet.io', 'key@yandex.ru', 'sergey@gmail.com', 'vovan@gmail.com', 'vovan@hotmail.com', ]; const freeEmailDomains = ['gmail.com', 'yandex.ru']; getFreeDomainsCount(emails); // { // 'gmail.com': 3, // 'yandex.ru': 2, // };
现有问题代码
const getFreeDomainsCount = (emails) => { emails.filter((item) => item.includes('gmail.com') || item.includes('yandex.ru')); emails.map((item) => {item.split('@')}); /*emails.reduce ((acc, item) => { let [,a] = item; if (acc.hasOwnProperty([,a])) { acc[[,a]] += 1; } else { acc[[,a]] = 1; } return acc }, {}) */ }; console.log (getFreeDomainsCount(emails));
要求必须使用filter、map或reduce等高阶函数,修正代码完成函数编写。
解决方案
你的代码存在几个核心问题:
filter和map是纯方法,不会修改原数组,必须接收返回值才能处理后续逻辑- 硬编码判断域名不符合需求,应该用
freeEmailDomains常量做统一判断 reduce里的解构逻辑错误:没有对拆分后的数组解构,且键名写法错误
修正后的完整代码
const freeEmailDomains = ['gmail.com', 'yandex.ru']; const getFreeDomainsCount = (emails) => { // 用reduce一步完成过滤和统计,避免多次遍历 return emails.reduce((counts, email) => { // 拆分邮箱获取域名 const domain = email.split('@')[1]; // 仅统计免费域名的邮箱 if (freeEmailDomains.includes(domain)) { // 计数:存在则加1,不存在则初始化为1 counts[domain] = (counts[domain] || 0) + 1; } return counts; }, {}); }; // 测试示例 const emails = [ 'info@gmail.com', 'info@yandex.ru', 'info@hotmail.com', 'mk@host.com', 'support@hexlet.io', 'key@yandex.ru', 'sergey@gmail.com', 'vovan@gmail.com', 'vovan@hotmail.com', ]; console.log(getFreeDomainsCount(emails)); // 输出:{ 'gmail.com': 3, 'yandex.ru': 2 }
代码说明
- 直接使用
reduce遍历邮箱列表,同时完成过滤免费域名和统计数量两个操作,减少遍历次数提升效率 - 每次遍历拆分邮箱得到域名,判断是否在免费域名列表中,符合条件则更新计数
counts[domain] = (counts[domain] || 0) + 1是简化写法:如果当前域名未统计过,counts[domain]为undefined,undefined || 0取0,再加1完成初始化;已统计过则直接加1
如果你偏好拆分步骤(先过滤再统计),也可以写成:
const getFreeDomainsCount = (emails) => { // 先过滤出免费域名的邮箱 const freeEmails = emails.filter(email => { const domain = email.split('@')[1]; return freeEmailDomains.includes(domain); }); // 再统计每个域名的数量 return freeEmails.reduce((counts, email) => { const domain = email.split('@')[1]; counts[domain] = (counts[domain] || 0) + 1; return counts; }, {}); };
内容的提问来源于stack exchange,提问作者Michael Pomozov
相关产品推荐
相关产品推荐

