如何在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"} ] }
需要修改函数,实现:
- 按
grade分组 - 插入
vec_of_vals中缺失的grade(如three)并对应空数组 - 移除不在
vec_of_vals中的grade(如five、six) - 维持
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
相关产品推荐
相关产品推荐

