如何在JavaScript中从表单条目数组创建多对象结构的食谱数据?
处理表单数据:将FormData条目数组转换为结构化食谱对象
我从FormData拿到的表单数据是一个条目数组,包含食谱的相关信息,示例如下:
const dataArr = [ ['title', 'pizza'], ['image', 'url'], ['quantity-0', '1'], ['unit-0', 'kg'], ['description-0', 'Flour'], ['quantity-1', '2'], ['unit-1', 'tbsp'], ['description-1', 'Olive oil'], ... // 更多配料 ];
需要把它转换成如下格式的结构化对象:
const recipe = { title: 'pizza', image: 'url', ingredients: [ { quantity: '1', unit: 'kg', ingredient: 'Flour' }, { quantity: '2', unit: 'tbsp', ingredient: 'Olive oil' }, ... ], };
其中ingredients数组需要根据现有数据生成多个对象。我自己写了一个解决方案,但代码不够简洁,而且只能支持最多6种配料,想要一个适配未知配料数量的通用函数。
我的现有实现:
const ingredients = []; // 创建长度为6的数组,通过索引循环获取对应配料数据 const arrayOf6 = new Array(6).fill({}); arrayOf6.forEach((_, i) => { // 每次循环过滤出当前索引对应的配料相关数据 const ingArr = dataArr.filter(entry => { return entry[0].startsWith(`unit-${i}`) || entry[0].startsWith(`quantity-${i}`) || entry[0].startsWith(`ingredient-${i}`); }); // 重命名配料数据的键名 ingArr.forEach(entry => { [key, value] = entry; if(key.includes('ingredient')) entry[0] = 'description'; if(key.includes('quantity')) entry[0] = 'quantity'; if(key.includes('unit')) entry[0] = 'unit'; }); // 转换为对象并推入配料数组 const ingObj = Object.fromEntries(ingArr); ingredients.push(ingObj); }); // 组装最终食谱对象 const dataObj = Object.fromEntries(dataArr); const recipe = { title: dataObj.title, image: dataObj.image, ingredients, };
通用优化方案
下面是适配任意数量配料的简洁实现,核心思路是通过配料的索引值分组,一次性遍历完成数据转换:
function transformToRecipe(dataArr) { const recipe = { ingredients: [] }; const ingredientGroups = new Map(); for (const [key, value] of dataArr) { // 匹配配料相关的键(如quantity-0、unit-1) const match = key.match(/^(quantity|unit|description)-(\d+)$/); if (match) { const [_, prop, indexStr] = match; const index = Number(indexStr); // 确保对应索引的配料对象存在 if (!ingredientGroups.has(index)) { ingredientGroups.set(index, {}); } // 映射键名:description对应ingredient,其余保持原名称 const mappedProp = prop === 'description' ? 'ingredient' : prop; ingredientGroups.get(index)[mappedProp] = value; } else { // 非配料字段直接赋值给recipe recipe[key] = value; } } // 将分组后的配料按索引顺序转为数组 recipe.ingredients = Array.from(ingredientGroups.values()); return recipe; } // 使用示例 const recipe = transformToRecipe(dataArr);
思路说明:
- 遍历原始数组,区分普通字段和配料字段
- 用
Map按配料的索引值(如0、1)分组存储配料属性 - 自动映射
description为目标格式的ingredient键名 - 最后将Map中的值转为数组,保证配料顺序和原始数据一致
- 无需预先指定配料数量,完全适配任意数量的配料条目
内容的提问来源于stack exchange,提问作者Alina Aleks
相关产品推荐
相关产品推荐

