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

基于product_id合并对象并排序的JavaScript代码优化咨询

如何优化基于product_id合并大型对象并排序的JavaScript代码?

我有两个大型对象(为便于理解已简化示例),需要基于product_id将二者合并、提取所需属性,完成后进行排序,但当前实现耗时较长,请问该如何优化?

原实现代码

const productsList = {
  27: {
    id: 2,
    limit: 4363614,
    initial_limit: '1',
    date: null,
  },
  59: {
    id: 13,
    limit: 757502,
    initial_limit: '1',
    date: null,
  },
  62: {
    id: 30,
    limit: 394878,
    initial_limit: '2',
    date: null,
  },
};

const updatingDataList = {
  updatedData: {
    '1INCHEQC': {
      open_value: 0.2834,
      high_value: 0.2954,
      prcing: 68357.32,
      volume: 237875,
      product_id: 59,
    },
    '2INCHEQF': {
      open_value: 82.79,
      high_value: 88.54,
      low: 81.99,
      prcing: 62054.321,
      volume: 739,
      product_id: 62,
    },
    '3INCHEQS': {
      open_value: 0.2806,
      high_value: 0.2975,
      prcing: 300550.43,
      volume: 1053694,
      product_id: 89,
    },
  },

  originalData: {
    59: '23.123',
    62: '3452.21',
    89: '456.11',
  },
};

// 基于product_id合并两个对象
const productsListUpdatingDataListAndOriginalDataMergedObject = Object.keys(
  productsList
)?.reduce((result, productId) => {
  const matchingUpdatingData = Object.values(updatingDataList.updatedData)?.find(
    item => item.product_id === parseInt(productId, 10)
  );

  if (matchingUpdatingData) {
    // 提取productList中需要的属性
    const { limit } = productsList[productId];

    result[productId] = {
      limit,
      updated_data: { ...matchingUpdatingData, originalData: updatingDataList.originalData[productId] },
    };
  }

  return result;
}, {});

// 排序处理
const sortedData = Object.values(
  productsListUpdatingDataListAndOriginalDataMergedObject
)?.sort(
  (firstProduct, secondProduct) =>
    secondProduct.updated_data.originalData - firstProduct.updated_data.originalData
);

console.log(sortedData);

优化思路及方案

1. 预处理updatedData,构建product_id映射表

原代码中每次遍历productsList的key时,都要调用Object.values(updatingDataList.updatedData).find(),这是O(n)的重复遍历操作,当数据量大时时间复杂度会飙升至O(m*n)(m为productsList长度,n为updatedData长度)。

我们可以先把updatedData转换成以product_id为键的对象,后续查找直接通过键访问,时间复杂度降至O(1):

// 预处理生成product_id到对应数据的映射
const updatedDataMap = Object.values(updatingDataList.updatedData).reduce((map, item) => {
  map[item.product_id] = item;
  return map;
}, {});

2. 简化合并逻辑,减少重复计算

利用预处理好的映射表,合并时直接通过product_id快速获取对应数据,避免重复遍历,同时把parseInt的操作提前,减少重复转换。

3. 显式转换排序字段类型

原排序逻辑中originalData是字符串类型,减法会隐式转换为数字,但显式转换为浮点数更清晰,也能避免潜在的类型错误。

优化后的完整代码

const productsList = {
  27: {
    id: 2,
    limit: 4363614,
    initial_limit: '1',
    date: null,
  },
  59: {
    id: 13,
    limit: 757502,
    initial_limit: '1',
    date: null,
  },
  62: {
    id: 30,
    limit: 394878,
    initial_limit: '2',
    date: null,
  },
};

const updatingDataList = {
  updatedData: {
    '1INCHEQC': {
      open_value: 0.2834,
      high_value: 0.2954,
      prcing: 68357.32,
      volume: 237875,
      product_id: 59,
    },
    '2INCHEQF': {
      open_value: 82.79,
      high_value: 88.54,
      low: 81.99,
      prcing: 62054.321,
      volume: 739,
      product_id: 62,
    },
    '3INCHEQS': {
      open_value: 0.2806,
      high_value: 0.2975,
      prcing: 300550.43,
      volume: 1053694,
      product_id: 89,
    },
  },

  originalData: {
    59: '23.123',
    62: '3452.21',
    89: '456.11',
  },
};

// 预处理updatedData,生成product_id映射表,O(n)时间
const updatedDataMap = Object.values(updatingDataList.updatedData).reduce((map, item) => {
  map[item.product_id] = item;
  return map;
}, {});

// 合并数据,O(m)时间(m为productsList长度)
const mergedObject = Object.keys(productsList).reduce((result, productId) => {
  const numProductId = parseInt(productId, 10);
  const matchingData = updatedDataMap[numProductId];
  
  if (matchingData) {
    result[productId] = {
      limit: productsList[productId].limit,
      updated_data: {
        ...matchingData,
        originalData: updatingDataList.originalData[productId]
      }
    };
  }
  
  return result;
}, {});

// 排序,显式转换为浮点数,避免隐式转换问题
const sortedData = Object.values(mergedObject).sort((a, b) => {
  const numA = parseFloat(a.updated_data.originalData);
  const numB = parseFloat(b.updated_data.originalData);
  return numB - numA;
});

console.log(sortedData);

优化效果说明

  • 时间复杂度从原有的O(m*n + k log k)(k为合并后数据长度)降至O(n + m + k log k),在数据量较大时性能提升明显。
  • 代码逻辑更清晰,减少了重复遍历和转换操作,显式类型转换也提升了代码可靠性。

内容的提问来源于stack exchange,提问作者dev

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 00:23:24