如何向嵌套对象中动态追加键值对?
问题:构建嵌套分类对象时子分类被覆盖的解决方案
我尝试构建一个可添加分类与子分类的对象,但每次添加时,嵌套对象仅保留最后添加的元素,之前的内容都被覆盖了。我试过用Object.assign()和{...obj, key:value}方法,都没解决问题。
我是通过多层for循环,在数据库查询后逐个添加键值对的。
期望的对象结构
{ category1: { subcategory1: null, subcategory2: null, subcategory3: { microcategory1: null } }, category2: { subcategory1: null, subcategory2: null, subcategory3: null } }
实际得到的结构
{ cooking: { 'ranges': null }, sinks: { 'filters': null } }
cooking和sinks原本应该各包含10+个子分类。
当前代码
let categoriesDictObj = {}; for (var index = 0; index < categories.length; index++) { let category = categories[index]; const subCategories = await Product.find({ productCategory: category, }).distinct("productSubCategory"); for ( var subCatIndex = 0; subCatIndex < subCategories.length; subCatIndex++ ) { let subCategory = subCategories[subCatIndex]; const microCategories = await Product.find({ productMicroCategory: subCategory, }).distinct("productMicroCategory"); // categoriesDictObj[category] = { [subCategory]: null }; // Object.assign(categoriesDictObj, { // [category]: { [subCategory]: null }, // }); categoriesDictObj = { ...categoriesDictObj, [category]: { [subCategory]: subCatIndex }, }; } }
问题原因
你每次处理子分类时,都直接给categoriesDictObj[category]赋值了一个全新的对象{ [subCategory]: subCatIndex },这会完全覆盖该分类下之前已有的所有子分类,自然最后只保留了最后一个子分类。不管是直接赋值、Object.assign还是扩展运算符,只要你每次都重新创建整个分类对象而不合并原有内容,就会出现这个问题。
解决方案
每次添加子分类时,先保留该分类下已有的子分类,再把新的子分类合并进去。具体来说,先检查当前分类是否已经存在于对象中,如果不存在就初始化一个空对象;然后把新的子分类添加到这个已有的(或新建的)分类对象里。
修改后的代码
let categoriesDictObj = {}; for (var index = 0; index < categories.length; index++) { let category = categories[index]; const subCategories = await Product.find({ productCategory: category, }).distinct("productSubCategory"); // 初始化当前分类的对象(不存在则创建空对象) if (!categoriesDictObj[category]) { categoriesDictObj[category] = {}; } for ( var subCatIndex = 0; subCatIndex < subCategories.length; subCatIndex++ ) { let subCategory = subCategories[subCatIndex]; // 注意:此处查询条件可能需要调整为productSubCategory: subCategory,根据你的数据库字段实际情况修改 const microCategories = await Product.find({ productSubCategory: subCategory, }).distinct("productMicroCategory"); // 处理微分类:有微分类则生成对应对象,否则设为null const subCatValue = microCategories.length > 0 ? Object.fromEntries(microCategories.map(micro => [micro, null])) : null; // 直接给当前分类的子分类赋值,不会覆盖其他子分类 categoriesDictObj[category][subCategory] = subCatValue; } }
代码说明
- 初始化分类对象:在处理每个分类前,先判断该分类是否已存在,不存在则创建空对象,确保后续子分类都添加到同一个对象中。
- 保留原有子分类:通过
categoriesDictObj[category][subCategory]直接赋值,只会新增或更新当前子分类,不会影响该分类下的其他子分类。 - 微分类处理:根据查询到的微分类数组,用
Object.fromEntries快速生成嵌套对象,符合你期望的结构;无分类时设为null。
内容的提问来源于stack exchange,提问作者Lawrence_matei
相关产品推荐
相关产品推荐

