如何使用JavaScript动态创建并填充以编程语言命名的用户ID数组?
优雅实现按语言分组用户ID的方案
嘿,这个需求其实用JavaScript的数组和对象方法就能非常优雅地搞定,不用写一堆冗余的判断或者手动声明每个数组变量~下面给你几种简洁的实现方式,从易读到高效都有覆盖:
基础易读版
这个版本逻辑清晰,新手也能一眼看懂,适合大多数场景:
const tags = ["js", "ruby", "ios", "python", "go"]; const users = [ { "id": "userId_1", "language": ["ruby", "ios"] }, { "id": "userId_2", "language": ["js", "python"] }, { "id": "userId_3", "language": ["ruby", "go"] } ]; // 第一步:初始化一个以目标语言为键的空对象,每个键对应空数组 const languageUsers = tags.reduce((acc, tag) => { acc[tag] = []; return acc; }, {}); // 第二步:遍历所有用户,把ID填充到对应的语言数组中 users.forEach(user => { user.language.forEach(lang => { // 只处理我们预先定义的tags里的语言,避免意外的键 if (languageUsers[lang]) { languageUsers[lang].push(user.id); } }); }); // 如果需要单独的变量(比如你要的const ruby = [...]),直接解构即可 const { js, ruby, ios, python, go } = languageUsers; console.log(ruby); // 输出: ["userId_1", "userId_3"]
紧凑优化版
如果想把逻辑合并成一步,同时优化性能(尤其是当tags数组很大时),可以用下面的写法:
const tags = ["js", "ruby", "ios", "python", "go"]; const users = [ { "id": "userId_1", "language": ["ruby", "ios"] }, { "id": "userId_2", "language": ["js", "python"] }, { "id": "userId_3", "language": ["ruby", "go"] } ]; // 把tags转成Set,判断语言是否在目标列表里的性能从O(n)变成O(1) const tagSet = new Set(tags); // 用Object.fromEntries初始化对象,同时在reduce里完成用户ID的填充 const languageUsers = users.reduce((acc, user) => { user.language.forEach(lang => { if (tagSet.has(lang)) { acc[lang].push(user.id); } }); return acc; }, Object.fromEntries(tags.map(tag => [tag, []]))); // 同样可以解构出单独的变量 const { js, ruby, ios, python, go } = languageUsers;
为什么这两种方式优雅?
- 可维护性:以后要新增或者修改目标语言,只需要调整
tags数组,不用改动后面的逻辑 - 无冗余代码:不用手动声明每个语言数组,避免重复劳动
- 性能友好:尤其是第二个版本用了
Set来做存在性判断,处理大量数据时效率更高
内容的提问来源于stack exchange,提问作者Xavier
相关产品推荐
相关产品推荐

