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

如何更优雅地从嵌套对象数组中提取key属性?

更优雅地提取嵌套对象中的key属性

你现在的需求是从带有嵌套children的对象数组里提取所有key属性,并且要去重,原来的命令式写法确实有点依赖外部状态,不够函数式。我来给你几个更优雅的纯函数式实现方案。

先回顾下你的数据结构:

{ 
  "items": [ 
    { 
      "key":"main", 
      "foo":"bar", 
      "children":[ 
        { "key":"one", "foo":"barboo" }, 
        { "key":"two", "foo":"boobaz" } 
      ] 
    }, 
    { 
      "key":"secondary", 
      "foo":"baz", 
      "children":[ 
        { "key":"one", "foo":"barboobaz" }, 
        { "key":"two", "foo":"boobazfoo" } 
      ] 
    } 
  ] 
}

原来的写法依赖类的实例变量contentKeys,属于命令式风格,还带有副作用,而且去重的判断逻辑~!this.contentKeys.indexOf(item.key)也有点晦涩。下面是几个更优的函数式实现:

方案一:纯递归+FlatMap+Set去重

这是最简洁的实现方式,完全是纯函数,没有任何副作用:

const extractAllKeys = (items) => {
  // 递归收集单个对象及其子元素的key
  const collectKeys = ({ key, children = [] }) => [
    key,
    ...children.flatMap(collectKeys)
  ];
  
  // 收集所有key → 去重 → 拼接成字符串
  return [...new Set(items.flatMap(collectKeys))].join(',');
};

为什么这个更好?

  • 纯函数特性:输入相同的items,输出一定相同,不依赖任何外部状态,单元测试起来特别方便
  • 函数式风格:用flatMap处理递归展开,扩展运算符...合并数组,避免了手动循环和状态修改
  • 可读性高:解构赋值直接拿到key和children,默认值处理children不存在的情况,逻辑一目了然
  • 高效去重:用Set去重的时间复杂度是O(n),比原来的indexOf(O(n²))高效得多

方案二:如果不需要去重

如果你的场景里不会出现重复的key,可以去掉Set部分,代码更简单:

const extractAllKeys = (items) => {
  const collectKeys = ({ key, children = [] }) => [
    key,
    ...children.flatMap(collectKeys)
  ];
  return items.flatMap(collectKeys).join(',');
};

使用示例

把你的测试数据传入函数:

const data = { /* 你的JSON数据 */ };
console.log(extractAllKeys(data.items));
// 输出:"main,one,two,secondary"

对比原来的写法,这些实现完全符合函数式编程的理念:无副作用、纯函数、声明式(告诉程序要做什么,而不是怎么做),代码也更简洁易维护。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:39:37