可以通过将任务分为两部分来轻松进行树转换:
- 用于转换单个节点的函数
- 一个用于转换节点数组的函数
要转换单个节点,我们写transform1
- 如果有没有个子节点,我们找到了叶子节点,返回单例节点
- 如果只有一个子节点,则删除节点并返回其唯一子节点的变换
- 否则节点有多个子节点,调用我们的第二个函数
transformAll
const transform1 = ({ children = [], ...node }) =>
children.length === 0 // leaf
? [ node ]
: children.length === 1 // singleton
? transform1 (...children)
: transformAll (children) // default
要转换一个节点数组,我们写transformAll -
const transformAll = (arr = []) =>
arr .flatMap (transform1)
如您所见,transformAll 调用transform1,后者也调用transformAll。这种技术称为mutual recursion,它是一种处理递归数据结构的好方法,就像您在问题中提出的那样。
为确保我们的功能正常工作,我修改了树以包含更多数据场景。请注意,我们的程序适用于任何具有children 属性的节点。所有其他属性都显示在结果中 -
const data =
[ { name: "a"
, children:
[ { name: "a.a"
, children:
[ { name: "a.a.a"
, children: []
}
, { name: "a.a.b"
, foo: 123
, children: []
}
]
}
]
}
, { name: "b"
, children:
[ { name: "b.a"
, children:
[ { name: "b.a.a"
, children: []
}
, { name: "b.a.b"
, children: []
}
]
}
, { name: "b.b"
, children: []
}
]
}
, { name: "c"
, children: []
}
]
我们可以在您的数据上运行transformAll 来转换所有个节点 -
transformAll (data)
// [ { name: 'a.a.a' }
// , { name: 'a.a.b', foo: 123 }
// , { name: 'b.a.a' }
// , { name: 'b.a.b' }
// , { name: 'b.b' }
// , { name: 'c' }
// ]
或者要转换一个单个节点,我们调用transform1 -
transform1 (data[0])
// [ { name: 'a.a.a' }
// , { name: 'a.a.b', foo: 123 }
// ]
transform1 (data[2])
// [ { name: 'c' } ]
展开下面的sn-p,在自己的浏览器中验证结果-
const data =
[ { name: "a"
, children:
[ { name: "a.a"
, children:
[ { name: "a.a.a"
, children: []
}
, { name: "a.a.b"
, foo: 123
, children: []
}
]
}
]
}
, { name: "b"
, children:
[ { name: "b.a"
, children:
[ { name: "b.a.a"
, children: []
}
, { name: "b.a.b"
, children: []
}
]
}
, { name: "b.b"
, children: []
}
]
}
, { name: "c"
, children: []
}
]
const transform1 = ({ children = [], ...node }) =>
children.length === 0 // leaf
? [ node ]
: children.length === 1 // singleton
? transform1 (...children)
: transformAll (children) // default
const transformAll = (arr = []) =>
arr .flatMap (transform1)
console .log (transformAll (data))
// [ { name: 'a.a.a' }
// , { name: 'a.a.b', foo: 123 }
// , { name: 'b.a.a' }
// , { name: 'b.a.b' }
// , { name: 'b.b' }
// , { name: 'c' }
// ]