嵌套forEach处理双JSON:重复值标红与非重复值去重需求
嘿,我来帮你搞定这个问题!核心问题出在你用的嵌套forEach上——它会让两个数组的元素逐一配对比对,导致同一个非重复元素被多次输出,重复元素也会被反复标记,完全不符合你要的“非重复只显示一次、重复值标红”的需求。
问题根源分析
嵌套forEach的逻辑是:遍历第一个数组的每个元素,再遍历第二个数组的每个元素做比对。举个例子,如果第一个数组有["苹果", "香蕉"],第二个数组有["葡萄", "苹果"],那么:
- 第一个数组的
苹果会和第二个数组的葡萄比对(不重复,输出一次),再和苹果比对(重复,标红输出一次) - 第一个数组的
香蕉会和第二个数组的葡萄、苹果分别比对(都不重复,输出两次)
结果就是苹果出现两次,香蕉出现两次,完全不是你想要的效果。
解决方案:先统计频次,再按需渲染
正确的思路是先把两个JSON的数据集合并,统计每个元素的出现总次数,再根据次数来决定显示样式:次数>1的标红,次数=1的只显示一次。
情况1:数组元素是简单类型(字符串/数字)
假设你的两个JSON返回的是简单数组,比如水果名称:
// 模拟从JSON读取的两个数组 const jsonData1 = ["苹果", "香蕉", "橙子", "草莓"]; const jsonData2 = ["香蕉", "苹果", "猕猴桃", "芒果"]; // 1. 合并两个数组 const combinedData = [...jsonData1, ...jsonData2]; // 2. 统计每个元素的出现频次 const frequencyMap = combinedData.reduce((acc, item) => { acc[item] = (acc[item] || 0) + 1; return acc; }, {}); // 3. 渲染到页面(这里以DOM渲染为例,你也可以输出到控制台) const resultDiv = document.getElementById("result"); Object.entries(frequencyMap).forEach(([item, count]) => { const textNode = document.createElement("span"); textNode.textContent = item; // 重复值标红 if (count > 1) { textNode.style.color = "#ff0000"; textNode.style.fontWeight = "bold"; // 可选:加粗突出 } resultDiv.appendChild(textNode); resultDiv.appendChild(document.createTextNode(" ")); // 加空格分隔元素 });
情况2:数组元素是对象(根据指定键判断重复)
如果你的JSON返回的是对象数组,比如每个对象有id或name等唯一标识,我们需要先提取判断重复的键值再统计:
// 模拟从JSON读取的对象数组 const jsonData1 = [ { id: 1, productName: "无线耳机", price: 299 }, { id: 2, productName: "机械键盘", price: 499 }, { id: 3, productName: "鼠标", price: 99 } ]; const jsonData2 = [ { id: 4, productName: "无线耳机", price: 329 }, { id: 5, productName: "显示器", price: 1299 }, { id: 6, productName: "鼠标", price: 119 } ]; // 1. 提取用于判断重复的键(这里用productName) const productNames = [ ...jsonData1.map(item => item.productName), ...jsonData2.map(item => item.productName) ]; // 2. 统计频次 const nameFrequency = productNames.reduce((acc, name) => { acc[name] = (acc[name] || 0) + 1; return acc; }, {}); // 3. 去重并渲染(用Set获取唯一的产品名称) const uniqueProducts = [...new Set(productNames)]; const resultDiv = document.getElementById("result"); uniqueProducts.forEach(name => { const textNode = document.createElement("span"); textNode.textContent = name; if (nameFrequency[name] > 1) { textNode.style.color = "#ff0000"; } resultDiv.appendChild(textNode); resultDiv.appendChild(document.createTextNode(" ")); });
为什么这个方法可行?
- 先合并再统计频次,能准确知道每个元素总共出现了多少次,不管它来自哪个JSON文件
- 用
Set或者遍历频次对象的键,能确保每个元素只被渲染一次,完美解决非重复值多次出现的问题 - 最后根据频次判断是否标红,逻辑清晰,不会出现重复标记的情况
内容的提问来源于stack exchange,提问作者Camilo Andres
相关产品推荐
相关产品推荐

