You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript实现推送新orderId时按前缀递增指定noOfSubmit值

需求描述

我们需要实现一个数组操作逻辑,向包含对象的数组推送新对象时,遵循以下规则:

  1. 推送新对象时,若新对象的orderId的前缀(按-拆分后的首段)对应的同前缀orderId是首次出现,则数组中所有拥有相同前缀的已有对象的noOfSubmit值递增1;若推送的是同前缀下已存在的orderId,则不执行递增操作。
  2. 不同前缀的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,避免重复处理同一ID
  • prefixOrderMap:以前缀为键,对应前缀下所有已出现的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 06:27:12