JavaScript实现推送新orderId时按前缀递增指定noOfSubmit值
需求描述
我们需要实现一个数组操作逻辑,向包含对象的数组推送新对象时,遵循以下规则:
- 推送新对象时,若新对象的
orderId的前缀(按-拆分后的首段)对应的同前缀orderId是首次出现,则数组中所有拥有相同前缀的已有对象的noOfSubmit值递增1;若推送的是同前缀下已存在的orderId,则不执行递增操作。 - 不同前缀的
orderId互相不产生影响。
基础规则示例
初始数组:
[ {"orderId":1,"noOfSubmit":1,"orderNo":"A"}, {"orderId":1,"noOfSubmit":1,"orderNo":"B"}, {"orderId":1,"noOfSubmit":1,"orderNo":"C"}, {"orderId":1,"noOfSubmit":1,"orderNo":"D"} ]
- 推送
{"orderId":2,"noOfSubmit":1,"orderNo":"E"}后,所有orderId=1的对象noOfSubmit变为2; - 推送
{"orderId":2,"noOfSubmit":1,"orderNo":"F"},无递增操作; - 推送
{"orderId":3,"noOfSubmit":1, "orderNo":"G"},所有orderId=1和orderId=2的对象noOfSubmit分别递增为3和2; - 推送
{"orderId":3,"noOfSubmit":1, "orderNo":"H"},无递增操作。
前缀匹配补充规则示例
当orderId包含-时,按-拆分取首段作为匹配前缀(如orderId为R1-1的前缀是R1),不同前缀的orderId互不影响:
初始数组:
[ {"orderId":"R1-1","noOfSubmit":1,"orderNo":"A"}, {"orderId":"R1-1","noOfSubmit":1,"orderNo":"B"}, {"orderId":"R1-1","noOfSubmit":1,"orderNo":"C"}, {"orderId":"R1-1","noOfSubmit":1,"orderNo":"D"} ]
- 推送
{"orderId":"R1-2","noOfSubmit":1,"orderNo":"E"},所有前缀为R1的对象noOfSubmit变为2; - 推送
{"orderId":"R1-2","noOfSubmit":1,"orderNo":"F"},无递增操作; - 推送
{"orderId":"R1","noOfSubmit":1,"orderNo":"G"},所有前缀为R1的对象noOfSubmit变为3; - 推送
{"orderId":"R2","noOfSubmit":1,"orderNo":"H"},无递增操作; - 推送
{"orderId":"R2","noOfSubmit":1,"orderNo":"I"},无递增操作; - 推送
{"orderId":"R3","noOfSubmit":1,"orderNo":"I"},无递增操作。
实现方案
核心思路
通过两个集合追踪已出现的orderId和前缀对应的orderId集合:
allOrderIds:记录所有已推送过的完整orderId,避免重复处理同一IDprefixOrderMap:以前缀为键,对应前缀下所有已出现的orderId集合为值,判断当前ID是否是该前缀下的新ID
代码实现
// 用闭包维护追踪状态,避免全局变量污染 const createOrderPusher = () => { const allOrderIds = new Set(); const prefixOrderMap = new Map(); // 提取orderId的前缀 const getOrderPrefix = (orderId) => { return String(orderId).split('-')[0]; }; return (targetArray, newOrder) => { const newOrderIdStr = String(newOrder.orderId); const prefix = getOrderPrefix(newOrder.orderId); // 若该orderId已存在,直接推送不处理 if (allOrderIds.has(newOrderIdStr)) { targetArray.push(newOrder); return; } // 标记该orderId已存在 allOrderIds.add(newOrderIdStr); // 初始化前缀对应的集合(如果不存在) if (!prefixOrderMap.has(prefix)) { prefixOrderMap.set(prefix, new Set()); } const prefixOrders = prefixOrderMap.get(prefix); // 若当前前缀下已有其他orderId,递增同前缀对象的noOfSubmit if (prefixOrders.size > 0) { targetArray.forEach(item => { if (getOrderPrefix(item.orderId) === prefix) { item.noOfSubmit += 1; } }); } // 将当前orderId加入前缀集合 prefixOrders.add(newOrderIdStr); // 推送新对象到数组 targetArray.push(newOrder); }; }; // 创建推送实例 const pushOrder = createOrderPusher();
验证示例
基础规则验证
// 初始数组 let orders = [ {"orderId":1,"noOfSubmit":1,"orderNo":"A"}, {"orderId":1,"noOfSubmit":1,"orderNo":"B"}, {"orderId":1,"noOfSubmit":1,"orderNo":"C"}, {"orderId":1,"noOfSubmit":1,"orderNo":"D"} ]; // 推送orderId=2 pushOrder(orders, {"orderId":2,"noOfSubmit":1,"orderNo":"E"}); console.log(orders.filter(item => item.orderId === 1).every(item => item.noOfSubmit === 2)); // true // 再次推送orderId=2 pushOrder(orders, {"orderId":2,"noOfSubmit":1,"orderNo":"F"}); console.log(orders.filter(item => item.orderId === 1).every(item => item.noOfSubmit === 2)); // true // 推送orderId=3 pushOrder(orders, {"orderId":3,"noOfSubmit":1, "orderNo":"G"}); console.log(orders.filter(item => item.orderId === 1).every(item => item.noOfSubmit === 3)); // true console.log(orders.filter(item => item.orderId === 2).every(item => item.noOfSubmit === 2)); // true
前缀匹配规则验证
// 创建新的推送实例,避免之前的测试数据干扰 const pushPrefixOrder = createOrderPusher(); // 初始数组 let prefixOrders = [ {"orderId":"R1-1","noOfSubmit":1,"orderNo":"A"}, {"orderId":"R1-1","noOfSubmit":1,"orderNo":"B"}, {"orderId":"R1-1","noOfSubmit":1,"orderNo":"C"}, {"orderId":"R1-1","noOfSubmit":1,"orderNo":"D"} ]; // 推送R1-2 pushPrefixOrder(prefixOrders, {"orderId":"R1-2","noOfSubmit":1,"orderNo":"E"}); console.log(prefixOrders.filter(item => getOrderPrefix(item.orderId) === 'R1').every(item => item.noOfSubmit === 2)); // true // 再次推送R1-2 pushPrefixOrder(prefixOrders, {"orderId":"R1-2","noOfSubmit":1,"orderNo":"F"}); console.log(prefixOrders.filter(item => getOrderPrefix(item.orderId) === 'R1').every(item => item.noOfSubmit === 2)); // true // 推送R1 pushPrefixOrder(prefixOrders, {"orderId":"R1","noOfSubmit":1,"orderNo":"G"}); console.log(prefixOrders.filter(item => getOrderPrefix(item.orderId) === 'R1').every(item => item.noOfSubmit === 3)); // true // 推送R2 pushPrefixOrder(prefixOrders, {"orderId":"R2","noOfSubmit":1,"orderNo":"H"}); console.log(prefixOrders.filter(item => getOrderPrefix(item.orderId) === 'R1').every(item => item.noOfSubmit === 3)); // true
内容的提问来源于Stack Exchange,提问作者Banu
相关产品推荐
相关产品推荐

