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

JavaScript如何按指定块大小/重复模式对对象数组自定义排序

特定分块排序实现方案

核心规则拆解

你要的排序逻辑本质是以Reference为分块基准,而非原始数组的索引,之前的实现错误点在于直接对原始数组按长度切分,没有对齐分块维度:

  • 分块对象是预排序后的去重Reference列表,不是原始数据条目
  • 每个Reference块内,按Step从小到大遍历取数
  • 前一个Reference块的所有Step条目全部取完,再处理下一个Reference块

以示例数据、chunk size=3为例,排序逻辑走查:

  1. 去重后有序Reference列表为['AA08','AA09','AA10','AA11'],切分后得到两个Reference块:['AA08','AA09','AA10']、['AA11']
  2. 处理第一个Reference块:
    • 取Step=1的三个条目:AA08-1、AA09-1、AA10-1
    • 取Step=2的三个条目:AA08-2、AA09-2、AA10-2
    • 取Step=3的三个条目:AA08-3、AA09-3、AA10-3
  3. 处理第二个Reference块:
    • 取Step=1的条目:AA11-1
    • 取Step=2的条目:AA11-2
    • 取Step=3的条目:AA11-3
      输出结果完全匹配你给出的期望顺序。

实现步骤

  • 提取有序去重Reference列表:遍历原始数据,按首次出现顺序收集Reference,保留原始数据预排序的Reference优先级(不需要重新按日期等规则排序)
  • 切分Reference块:按设定的chunk size,把有序Reference列表切成多个子组
  • 构建查找索引:以Reference-Step为键存储原始条目,避免后续取数时重复遍历数组
  • 按规则组装结果:遍历每个Reference块,块内按Step从小到大遍历,依次取出块内每个Reference对应当前Step的条目,按顺序塞入结果数组

可运行代码示例

const chunkSize = 3;
// 替换为实际从数据库查询返回的JSON数据
const jsonData = [
    { Reference: 'AA08', Date: '2022-06-22', Step: 1 },
    { Reference: 'AA09', Date: '2022-06-23', Step: 1 },
    { Reference: 'AA10', Date: '2022-06-24', Step: 1 },
    { Reference: 'AA11', Date: '2022-06-24', Step: 1 },
    { Reference: 'AA08', Date: '2022-06-22', Step: 2 },
    { Reference: 'AA09', Date: '2022-06-23', Step: 2 },
    { Reference: 'AA10', Date: '2022-06-24', Step: 2 },
    { Reference: 'AA11', Date: '2022-06-24', Step: 2 },
    { Reference: 'AA08', Date: '2022-06-22', Step: 3 },
    { Reference: 'AA09', Date: '2022-06-23', Step: 3 },
    { Reference: 'AA10', Date: '2022-06-24', Step: 3 },
    { Reference: 'AA11', Date: '2022-06-24', Step: 3 }
];

// 1. 提取有序去重Reference列表
const orderedReferences = [];
const seenRefs = new Set();
for (const item of jsonData) {
  if (!seenRefs.has(item.Reference)) {
    seenRefs.add(item.Reference);
    orderedReferences.push(item.Reference);
  }
}

// 2. 切分Reference块
const refChunks = [];
for (let i = 0; i < orderedReferences.length; i += chunkSize) {
  refChunks.push(orderedReferences.slice(i, i + chunkSize));
}

// 3. 构建条目查找索引
const itemIndex = new Map();
for (const item of jsonData) {
  const key = `${item.Reference}-${item.Step}`;
  itemIndex.set(key, item);
}

// 4. 组装最终排序结果
const processedData = [];
// 提取所有Step值并升序排列
const allSteps = [...new Set(jsonData.map(item => item.Step))].sort((a, b) => a - b);

for (const chunk of refChunks) {
  for (const step of allSteps) {
    for (const ref of chunk) {
      const targetItem = itemIndex.get(`${ref}-${step}`);
      if (targetItem) {
        processedData.push({
          ...targetItem,
          FullId: `${ref}-${step}` // 按需保留拼接后的完整标识字段
        });
      }
    }
  }
}

console.log(processedData);

原有代码问题说明

之前的实现直接对原始数组按索引做固定长度切分,而原始数据本身是按Step聚簇排列(所有Step=1条目在前,之后是Step=2、Step=3条目),切分后会把AA11-1划入第一个数据块,最终得到第一种不符合要求的排序结果,核心是分块的基准对象选错了。

内容的提问来源于stack exchange,提问作者Ben in CA

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 23:48:39