如何检查数组对象嵌套键值并实现重复标签的唯一渲染?
问题:如何渲染不重复的标签列表
我有一个包含嵌套对象的对象数组:
const data = [ { "operationId": "6357a5bba0de053fb601d573", "tags": { "120": { "title": "ac milan", "color": "red", "updated_at": "2022-10-25 08:52:00", "created_at": "2022-10-25 08:52:00", "_id": "6357a3b06891976bca0a9215" }, "121": { "title": "napoli", "color": "blue", "updated_at": "2022-10-25 08:54:12", "created_at": "2022-10-25 08:54:12", "_id": "6357a43470761099ce0049e0" } } }, { "operationId": "6357a5c9a0de053fb601d574", "tags": { "118": { "title": "ac roma", "color": "red", "updated_at": "2022-10-25 07:54:19", "created_at": "2022-10-25 07:54:19", "_id": "6357962b6891976bca0a920e" }, "120": { "title": "ac milan", "color": "red", "updated_at": "2022-10-25 08:52:00", "created_at": "2022-10-25 08:52:00", "_id": "6357a3b06891976bca0a9215" } } } ];
其中:
operationId- 文档ID;tags- 绑定到文档的标签对象。
我需要在页面中渲染标签列表,但同一个标签可能绑定到多个文档(如示例中的“ac milan”标签),此时该标签需仅渲染一次。当前的addExistingTagsToModal函数会重复渲染所有标签,现有代码如下:
function addExistingTagsToModal(arr) { let existingTagTitle, existingTagColor, existingTagID; const constructedData = arr.map(item => { const operationId = item?.operationId; const innerValues = Object.values(item.tags); return innerValues.map(subItem => { existingTagID = subItem._id; existingTagTitle = subItem.title; existingTagColor = subItem.color; let tagObjMarkup = { tagMarkup: `<li>${existingTagTitle}</li>` }; let addedTagList = document.querySelector('.list'); addedTagList.insertAdjacentHTML('afterbegin', tagObjMarkup.tagMarkup); return {...subItem, operationId}; }); }); }
解决方法
核心思路是先收集所有不重复的标签,再统一渲染,推荐用标签的_id作为去重依据(因为_id是唯一标识,比title更可靠,避免出现标题相同但实际是不同标签的情况)。
修改后的代码:
function addExistingTagsToModal(arr) { // 用Map存储不重复的标签,key为标签的唯一_id const uniqueTags = new Map(); // 遍历所有文档,提取标签并去重 arr.forEach(item => { Object.values(item.tags).forEach(tag => { // 仅当标签未被存储过,才加入Map if (!uniqueTags.has(tag._id)) { uniqueTags.set(tag._id, tag); } }); }); // 获取列表容器 const addedTagList = document.querySelector('.list'); // 清空容器(可选,防止多次调用函数时重复添加) addedTagList.innerHTML = ''; // 渲染所有去重后的标签 uniqueTags.forEach(tag => { const tagMarkup = `<li>${tag.title}</li>`; addedTagList.insertAdjacentHTML('afterbegin', tagMarkup); }); }
代码说明
- 去重逻辑:使用
Map结构,以标签的_id作为键,确保每个标签只被存储一次; - 统一渲染:先完成所有标签的收集和去重,再批量插入DOM,避免边遍历边渲染导致的重复;
- 可选清空容器:如果函数可能被多次调用,清空容器可以防止标签重复叠加。
如果确实需要根据title去重(忽略_id差异),只需把tag._id替换为tag.title即可,但不推荐这种方式,因为可能存在不同标签标题相同的场景。
内容的提问来源于stack exchange,提问作者Igor Merdich
相关产品推荐
相关产品推荐

