如何在嵌套数组对象中匹配购物车数据并实现数量累加或新增
购物车商品匹配与数量更新实现方案
需求说明
现有购物车数组dataCart和待添加商品数据inputData,需实现以下逻辑:
- 筛选
dataCart中与inputDataid相同的商品 - 对id相同的商品,进一步严格校验
group_option的嵌套结构是否完全一致 - 若存在完全匹配的商品,将该商品的
qty与inputData的qty相加 - 若没有匹配项(包括id不同,或id相同但
group_option不一致),则将inputData添加到dataCart数组中
核心难点:嵌套group_option的深度比较
由于group_option是嵌套数组/对象结构,直接用===无法判断是否完全一致,需实现深度比较函数。
实现步骤
- 编写深度比较函数,处理
group_option的null值、嵌套数组两种情况 - 遍历购物车数组,结合id匹配和group_option匹配查找目标商品
- 根据查找结果执行数量累加或添加新商品的操作
代码实现
1. 深度比较group_option的函数
function isGroupOptionsEqual(opt1, opt2) { // 两者都是null,判定为匹配 if (opt1 === null && opt2 === null) return true; // 其中一个为null,直接不匹配 if (opt1 === null || opt2 === null) return false; // 数组长度不同,直接不匹配 if (opt1.length !== opt2.length) return false; // 按选项组id排序,避免顺序不同导致误判(若要求顺序严格一致可去掉排序) const sortedOpt1 = [...opt1].sort((a, b) => a.id.localeCompare(b.id)); const sortedOpt2 = [...opt2].sort((a, b) => a.id.localeCompare(b.id)); for (let i = 0; i < sortedOpt1.length; i++) { const group1 = sortedOpt1[i]; const group2 = sortedOpt2[i]; // 选项组id、name不同,不匹配 if (group1.id !== group2.id || group1.name !== group2.name) return false; // 选项组内的option数组长度不同,不匹配 if (group1.option.length !== group2.option.length) return false; // 按选项name排序后比较 const sortedOption1 = [...group1.option].sort((a, b) => a.name.localeCompare(b.name)); const sortedOption2 = [...group2.option].sort((a, b) => a.name.localeCompare(b.name)); for (let j = 0; j < sortedOption1.length; j++) { const option1 = sortedOption1[j]; const option2 = sortedOption2[j]; // 选项name或price不同,不匹配 if (option1.name !== option2.name || option1.price !== option2.price) { return false; } } } return true; }
2. 购物车处理逻辑
// 查找匹配的商品索引 const matchIndex = dataCart.findIndex(item => { // 先匹配id if (item.id !== inputData.id) return false; // id相同的情况下,比较group_option return isGroupOptionsEqual(item.group_option, inputData.group_option); }); if (matchIndex !== -1) { // 找到匹配项,累加数量 dataCart[matchIndex].qty += inputData.qty; } else { // 无匹配项,添加新商品(浅拷贝避免原对象修改影响购物车) dataCart.push({...inputData}); }
代码说明
- 排序逻辑:如果允许选项组或选项的顺序不同但内容一致也算匹配,保留排序;如果要求顺序完全一致,可去掉排序步骤直接按原顺序比较。
- 浅拷贝
inputData是为了隔离原对象与购物车数据,根据实际业务需求可调整为深拷贝。
内容的提问来源于stack exchange,提问作者Toni
相关产品推荐
相关产品推荐

