如何更优雅地从嵌套对象数组中提取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
相关产品推荐
相关产品推荐

