JS按ProductName合并数组对象 保留产品最新版本条目
实现思路
整个逻辑拆成3个核心步骤即可:
- 以
ProductName为唯一标识归集所有产品条目 - 对同产品下的所有条目做版本号对比,筛选出版本最新的单条记录。注意版本号是点分语义化格式,不能直接用字符串比较,必须拆分为数字段逐位对比,避免出现
"9.0.0" > "10.0.0"的判断错误 - 保留原对象其他字段不变,将筛选出的最新产品条目组装为新的
Products数组返回
代码实现
原生JS版本(无第三方依赖)
// 语义化版本对比函数:a > b 返回1,a < b 返回-1,版本相等返回0 const compareVersion = (versionA, versionB) => { const segA = versionA.split('.').map(Number); const segB = versionB.split('.').map(Number); const maxSegLength = Math.max(segA.length, segB.length); for (let i = 0; i < maxSegLength; i++) { const numA = segA[i] ?? 0; const numB = segB[i] ?? 0; if (numA > numB) return 1; if (numA < numB) return -1; } return 0; }; const getLatestProductList = (originData) => { const productMap = new Map(); originData.Products.forEach(productItem => { const currentVer = productItem.ProductVersions[0]; const storedItem = productMap.get(productItem.ProductName); // 无同产品记录直接存入,有记录则保留版本更新的条目 if (!storedItem || compareVersion(currentVer, storedItem.ProductVersions[0]) > 0) { productMap.set(productItem.ProductName, productItem); } }); return { ...originData, Products: Array.from(productMap.values()) }; }; // 调用即可得到目标结果 const targetResult = getLatestProductList(testOb);
Lodash实现版本
import _ from 'lodash'; const compareVersion = (versionA, versionB) => { const segA = versionA.split('.').map(Number); const segB = versionB.split('.').map(Number); const maxSegLength = Math.max(segA.length, segB.length); for (let i = 0; i < maxSegLength; i++) { const numA = segA[i] ?? 0; const numB = segB[i] ?? 0; if (numA > numB) return 1; if (numA < numB) return -1; } return 0; }; const getLatestProductList = (originData) => { // 按产品名分组 const productGroups = _.groupBy(originData.Products, 'ProductName'); // 每组取版本最高的条目 const latestProducts = Object.values(productGroups).map(group => { return _.maxBy(group, item => { const verSegs = item.ProductVersions[0].split('.').map(Number); // 生成版本权重值供排序使用,适配三段式语义化版本 return verSegs[0] * 10000 + verSegs[1] * 100 + verSegs[2]; }); }); return { ...originData, Products: latestProducts }; };
注意:如果你的版本号段数不固定、或者段数值可能超过100,不要用权重计算的方式做对比,直接复用前面的compareVersion函数遍历对比更稳妥。
内容的提问来源于stack exchange,提问作者Oleh
相关产品推荐
相关产品推荐

