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

如何在JavaScript中按指定键向量分组数据、补全空数组并维持顺序?

问题描述

我需要使用以下键向量:

const vec_of_vals = ["one", "two", "three", "four"]

对如下对象数组进行分组和过滤:

const data = [
  {grade: "one"},
  {grade: "one"},
  {grade: "one"},
  {grade: "two"},
  {grade: "four"},
  {grade: "four"},
  {grade: "four"},
  {grade: "four"},
  {grade: "five"},
  {grade: "five"},
  {grade: "five"},
  {grade: "six"}
]

我尝试的代码无法生成vec_of_vals中存在的空"three"数组,也无法维持键向量的原始顺序:

function groupByKey(array, key) {
  return array.reduce((hash, obj) => {
    if (obj[key] === undefined) return hash;
    return Object.assign(hash, {
      [obj[key]]: (hash[obj[key]] || []).concat(obj),
    });
  }, {});
}

groupByKey(
  data.filter((x) => vec_of_vals.includes(x.grade)),
  "grade"
);

期望输出:

let desired_output = {
  "one" : [
    {grade: "one"},
    {grade: "one"},
    {grade: "one"},
  ],
  "two" : [
    {grade: "two"},
  ],
  "three" : [],
  "four" : [
    {grade: "four"},
    {grade: "four"},
    {grade: "four"},
    {grade: "four"}
  ]
}

需要修改函数,实现:

  1. 按grade分组
  2. 插入vec_of_vals中缺失的grade(如three)并对应空数组
  3. 移除不在vec_of_vals中的grade(如five、six)
  4. 维持vec_of_vals的原始顺序

解决方案

修改后的函数

先基于vec_of_vals初始化结果对象,确保所有指定键都存在且顺序一致,再遍历数据填充对应分组:

function groupByKeyWithSpecifiedKeys(array, key, specifiedKeys) {
  // 用指定键初始化结果对象,保证顺序和键向量一致,每个键对应空数组
  const result = specifiedKeys.reduce((acc, currentKey) => {
    acc[currentKey] = [];
    return acc;
  }, {});

  // 遍历数据,仅处理存在于指定键中的项
  array.forEach(item => {
    const itemKey = item[key];
    if (specifiedKeys.includes(itemKey)) {
      result[itemKey].push(item);
    }
  });

  return result;
}

// 使用示例
const vec_of_vals = ["one", "two", "three", "four"];
const data = [/* 你的数据数组 */];
const output = groupByKeyWithSpecifiedKeys(data, "grade", vec_of_vals);
console.log(output);

性能优化(针对大键向量场景)

如果vec_of_vals长度较大,用Set替换数组的includes可以将查找效率从O(n)提升到O(1):

function groupByKeyWithSpecifiedKeys(array, key, specifiedKeys) {
  const keySet = new Set(specifiedKeys);
  const result = specifiedKeys.reduce((acc, currentKey) => {
    acc[currentKey] = [];
    return acc;
  }, {});

  array.forEach(item => {
    const itemKey = item[key];
    if (keySet.has(itemKey)) {
      result[itemKey].push(item);
    }
  });

  return result;
}

效果说明

  • 初始化步骤保证了结果对象包含vec_of_vals的所有键,且顺序完全匹配
  • 遍历数据时自动过滤掉不在vec_of_vals中的grade(如five、six)
  • 未在data中出现的键(如three)会保留空数组

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 05:53:26