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

React中如何通过键名动态获取多层级JSON对象中的数据

如何通过点分隔的键名获取多层级JSON/对象的值?

我有如下多层级数据:

const data = {
    level11: "l11",
    level12: { level21: "l21", level22: { level31: "l31", level32: "l32" } },
    level13: [{ level131: "a" }, { level132: "b" }]
};

直接用data.level11这类方式能轻松拿到对应值,但现在我手里的键名是"level11"或者"level12.level22.level31"这种点分隔的格式。单层的键名可以用data["level11"]访问,但多层级的情况就搞不定了,而且数组类型的节点也处理不了。

我试过下面这个递归方法,但它没法处理数组或对象类型的返回值:

generateData = (data, key) => {
    if (!key.includes("."))
      return data[key];
    var p = key.split(".")[0];
    var ndata = data[p];
    if(!ndata) return;
    var newkey = key
      .split(".")
      .filter((o, i) => i !== 0)
      .join(".");
    return this.generateData(ndata, newkey);
};

完整的React组件代码如下:

export default function App() {
  const data = {
    level11: "l11",
    level12: { level21: "l21", level22: { level31: "l31", level32: "l32" } },
    level13: [{ level131: "a" }, { level132: "b" }]
  };
  generateData = (data, key) => {
    if (!key.includes("."))
      return data[key];
    var p = key.split(".")[0];
    var ndata = data[p];
    var newkey = key
      .split(".")
      .filter((o, i) => i !== 0)
      .join(".");
    return this.generateData(ndata, newkey);
  };
   
  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <span>{this.generateData(data, "level12.level22.level31")}</span>
    </div>
  );
}

解决方案

方法1:优化递归逻辑,兼容数组和对象

修改函数逻辑,确保每一步都能正确处理对象和数组类型的节点,同时支持数组索引格式的键名(比如level13.0):

const generateData = (data, key) => {
  // 空数据或空键直接返回
  if (!data || !key) return undefined;
  
  const keys = key.split(".");
  let current = data;
  
  for (const k of keys) {
    // 尝试将键转为数组索引
    const index = parseInt(k, 10);
    // 数组类型且索引有效时用索引访问,否则用键名访问
    current = Array.isArray(current) && !isNaN(index) ? current[index] : current[k];
    
    // 中途找不到对应值直接返回
    if (current === undefined) return undefined;
  }
  
  return current;
};

方法2:使用reduce简化实现

用数组reduce方法可以更简洁地实现相同逻辑,同样兼容对象和数组:

const generateData = (data, key) => {
  return key.split(".").reduce((current, k) => {
    if (!current) return undefined;
    const index = parseInt(k, 10);
    return Array.isArray(current) && !isNaN(index) ? current[index] : current[k];
  }, data);
};

修改后的完整组件代码

export default function App() {
  const data = {
    level11: "l11",
    level12: { level21: "l21", level22: { level31: "l31", level32: "l32" } },
    level13: [{ level131: "a" }, { level132: "b" }]
  };

  const generateData = (data, key) => {
    return key.split(".").reduce((current, k) => {
      if (!current) return undefined;
      const index = parseInt(k, 10);
      return Array.isArray(current) && !isNaN(index) ? current[index] : current[k];
    }, data);
  };

  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <div>level11: {generateData(data, "level11")}</div>
      <div>level12.level22.level31: {generateData(data, "level12.level22.level31")}</div>
      <div>level13.0.level131: {generateData(data, "level13.0.level131")}</div>
      <div>level13.1: {JSON.stringify(generateData(data, "level13.1"))}</div>
    </div>
  );
}

这个修改后的函数可以处理:

  • 普通对象的多层级键名(如level12.level22.level31)
  • 数组索引(如level13.0)
  • 返回对象/数组类型的值(比如level13.1会返回{ level132: "b" })

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 22:30:51