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

如何在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 04:27:27