JS对象数组过滤后按公共属性分组并动态渲染展示的实现方法
问题描述
我现有如下对象数组:
const students = [ { name: 'Tom', class: "Blue" }, { name: 'Pom', class: "Blue" }, { name: 'Max', class: "Red" }, { name: 'Alex', class: "Red" }, { name: 'John', class: "Yellow" } ];
我需要按class属性对返回值进行分组,最终在HTML中实现类似如下的展示效果:
Class Blue: Tom, Pom Class Red: Max, Alex Class Yellow: John
注意:class属性需要作为HTML标签只展示一次,因此我认为通用的groupby教程无法满足我的需求。
我该如何实现该需求? 目前我可以通过如下方式使用filter(),但这种写法非常冗余低效。
const classRed = students.filter(student => student.class === "Red"); const classBlue = students.filter(student => student.class === "Blue"); ...
我已经搭建了在线示例,但不清楚该如何处理这个对象来得到我想要的展示效果。
解决方案
你可以用数组的reduce方法一次性完成分组,再遍历分组结果渲染即可,全程只需要遍历原数组1次,支持任意数量的班级扩展,不用手动写多个filter:
步骤1:按班级分组得到结构化数据
// 分组后得到 班级名: 对应学生姓名数组 的结构 const groupedStudents = students.reduce((result, student) => { const className = student.class // 首次遇到该班级时初始化空数组 if (!result[className]) { result[className] = [] } result[className].push(student.name) return result }, {})
执行后groupedStudents的结构为:
{ Blue: ["Tom", "Pom"], Red: ["Max", "Alex"], Yellow: ["John"] }
步骤2:渲染到HTML中
假设你页面中有个用于展示的容器<div id="class-list"></div>,直接遍历分组结果渲染即可:
const listContainer = document.querySelector('#class-list') Object.entries(groupedStudents).forEach(([className, nameList]) => { const item = document.createElement('div') // 班级名只渲染一次,你也可以自定义标签样式 item.innerHTML = `<span class="class-label">Class ${className}:</span> ${nameList.join(', ')}` listContainer.appendChild(item) })
运行后就能得到你要的展示效果,后续新增班级也不需要修改代码,自动适配。
内容的提问来源于stack exchange,提问作者Christopher
相关产品推荐
相关产品推荐

