ReactJS中按genericProduct合并重组JS对象数组需求
按
genericProduct分组合并React产品JSON数据 我正在开发一个ReactJS应用,需要获取产品JSON数据并进行重组,实现分类展示的效果。我试过用filter和map方法,但没得到预期结果。
示例原始数据
[ { "barcode": "8434786768366", "collection": "AW", "colorCode": "413", "colorName": "LIGHT WINE", "familyCode": "1", "familyName": "T-Shirts", "genericProduct": "PM506471", "id": 263917, "productCode": "PM506471413S", "productName": "T-SHIRT", "productNameLang": "en", "season": "2019", "size": "S", "subfamilyName": "SS T-Shirts" }, { "barcode": "8434786768342", "collection": "AW", "colorCode": "413", "colorName": "LIGHT WINE", "familyCode": "1", "familyName": "T-Shirts", "genericProduct": "PM506471", "id": 263921, "productCode": "PM506471413L", "productName": "T-SHIRT", "productNameLang": "en", "season": "2019", "size": "L", "subfamilyName": "SS T-Shirts" } ]
实际的数组规模比这个大很多。
预期合并效果
我需要把所有拥有相同genericProduct的对象合并成单个对象,去除重复项的同时保留全部信息(不是覆盖)。合并后的示例如下:
[ { "barcode": ["8434786768366", "8434786768342"], "collection": "AW", "colorCode": "413", "colorName": "LIGHT WINE", "familyCode": "1", "familyName": "T-Shirts", "genericProduct": "PM506471", "id": [263917, 263921], "productCode": ["PM506471413S","PM506471413L"], "productName": "T-SHIRT", "productNameLang": "en", "season": "2019", "size": ["S","L"], "subfamilyName": "SS T-Shirts" } ]
简单来说,就是要遍历对象数组,按genericProduct分组,检查每个属性值,把不同的值转为数组存储。
解决方案
你可以用Array.reduce()来实现这个分组合并的逻辑,核心思路是先按genericProduct把对象分组,然后对每个分组里的对象逐个属性处理:如果属性值都相同就保留单个值,如果有不同就收集成数组(还要注意去重,避免重复值)。
下面是具体的代码实现:
const mergeProductsByGeneric = (products) => { // 第一步:按genericProduct分组 const grouped = products.reduce((acc, product) => { const key = product.genericProduct; if (!acc[key]) { acc[key] = []; } acc[key].push(product); return acc; }, {}); // 第二步:处理每个分组,合并属性 return Object.values(grouped).map(group => { return group.reduce((merged, item) => { // 遍历当前item的所有属性 Object.keys(item).forEach(key => { if (!merged[key]) { // 如果merged还没有这个属性,直接赋值 merged[key] = item[key]; } else if (merged[key] !== item[key]) { // 如果属性值不同,判断当前merged的属性是不是数组 if (!Array.isArray(merged[key])) { // 不是数组的话,先转成数组,把之前的值和当前值加进去 merged[key] = [merged[key]]; } // 避免重复添加相同的值 if (!merged[key].includes(item[key])) { merged[key].push(item[key]); } } // 如果值相同,什么都不用做 }); return merged; }, {}); }); }; // 使用示例 const originalProducts = [/* 你的原始数据数组 */]; const mergedProducts = mergeProductsByGeneric(originalProducts); console.log(mergedProducts);
代码说明
- 分组阶段:用
reduce把原始数组转换成以genericProduct为键、对应产品数组为值的对象,这样相同genericProduct的产品就被分到了一组。 - 合并阶段:对每个分组再次使用
reduce,逐个合并每个产品的属性:- 如果目标对象还没有该属性,直接赋值;
- 如果属性值不同,就把目标对象的属性转为数组(如果还不是数组的话),并添加新值(同时去重);
- 如果值相同则跳过,保留原有的值。
这个方法可以处理任意规模的产品数组,而且能自动识别哪些属性需要转成数组,哪些属性值是统一的不需要修改。
内容的提问来源于stack exchange,提问作者KuluGary
相关产品推荐
相关产品推荐

