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

如何创建含[index]子串时值转为数组的嵌套数据结构?

问题描述

输入数据

[{
  "name": "outField2",
  "value": "something"
}, {
  "name": "outField3[index].outField4",
  "value": "something"
}, {
  "name": "outField3[index].outField5",
  "value": "something"
}, {
  "name": "outField3[index].outField6.outField7",
  "value": "something"
}]

期望输出

要求根据子串[index]生成结构:不含该子串的字段为对象,含该子串的字段为数组,最终输出如下:

{
  "outField2": "something",
  "outField3[index]": [{
    "outField4": "something",
    "outField5": "something",
    "outField6": {
      "outField7": "something"
    }
  }]
}

当前代码问题

现有代码在不含[index]时能正常生成对象,但遇到含[index]的字段无法生成数组,尝试多种方案未解决:

function doThis(item, index) {
  let path = map[index].name.split(".");
  if (path.length > 1) {
    createNestedObject(mapOutput, path, map[index].value);
  } else {
    mapOutput[map[index].name] = map[index].value;
  };
};

function createNestedObject(element, path, value) {
  var lastElement = arguments.length === 3 ? path.pop() : false;

  for (var i = 0; i < path.length; i++) {
    if (path[i].includes('[index]')) {
      /*some logic here to push the child elements
      that do not contain [index] as an array into
      the ones that contain [index]*/
    } else {
      element = element[path[i]] = element[path[i]] || {};
    };
  }
  if (lastElement) element = element[lastElement] = value;

  return element;
};

const map = [{
  "name": "outField2",
  "value": "something"
}, {
  "name": "outField3[index].outField4",
  "value": "something"
}, {
  "name": "outField3[index].outField5",
  "value": "something"
}, {
  "name": "outField3[index].outField6.outField7",
  "value": "something"
}];
let mapOutput = {};

map.forEach(doThis);

let mapOutputJSON = JSON.stringify(mapOutput, null, 2);

console.log(mapOutputJSON);
解决方案

修改createNestedObject函数,针对含[index]的字段做特殊处理:当遇到该字段时,初始化一个包含空对象的数组(如果不存在的话),后续子字段都挂载到数组的第一个元素上。

修改后的完整代码:

function doThis(item) {
  let path = item.name.split(".");
  if (path.length > 1) {
    createNestedObject(mapOutput, path, item.value);
  } else {
    mapOutput[item.name] = item.value;
  }
};

function createNestedObject(element, path, value) {
  const lastElement = path.pop();

  for (let i = 0; i < path.length; i++) {
    const key = path[i];
    if (key.includes('[index]')) {
      // 初始化数组,若不存在则创建包含空对象的数组
      element[key] = element[key] || [{}];
      // 切换操作上下文到数组的第一个元素
      element = element[key][0];
    } else {
      // 普通对象字段,不存在则创建空对象
      element[key] = element[key] || {};
      element = element[key];
    }
  }

  // 为最后一个字段赋值
  element[lastElement] = value;
  return element;
};

const map = [{
  "name": "outField2",
  "value": "something"
}, {
  "name": "outField3[index].outField4",
  "value": "something"
}, {
  "name": "outField3[index].outField5",
  "value": "something"
}, {
  "name": "outField3[index].outField6.outField7",
  "value": "something"
}];
let mapOutput = {};

map.forEach(doThis);

const mapOutputJSON = JSON.stringify(mapOutput, null, 2);
console.log(mapOutputJSON);

关键逻辑说明

  • 遍历路径时,遇到含[index]的键:
    1. 若该键不存在,创建包含空对象的数组,确保后续子字段有挂载目标
    2. 将操作上下文切换到数组的第一个元素,所有子字段都会被添加到这个元素中
  • 普通键保持原有逻辑,不存在则创建空对象
  • 最后将对应值赋值给路径的最后一个字段

运行这段代码后,即可得到预期的输出结构。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 05:20:29