Swift:如何将视图层级结构扁平化为一维数组?
视图层级扁平化为一维数组:用flatMap还是传统遍历?
嘿,这个需求我之前也碰到过,咱们一步步来拆解~
首先看你的示例输出:[0, 1, 2, 3, 3.1, 3.2, 4],这其实是深度优先遍历(DFS)的先序遍历结果——先访问根节点,再依次递归访问每个子节点的完整子树,最后回到下一个兄弟节点。
用flatMap实现完全可行!
如果你的视图结构可以通过某个属性(比如children)获取子节点,那用递归+flatMap可以非常简洁地实现需求。假设每个视图节点的结构是这样的:
const rootView = { id: 0, children: [ { id: 1, children: [] }, { id: 2, children: [] }, { id: 3, children: [ { id: '3.1', children: [] }, { id: '3.2', children: [] } ]}, { id: 4, children: [] } ] };
对应的扁平化函数可以写成:
function flattenViews(view) { // 先取当前节点的id,再递归扁平化所有子节点并展开 return [view.id, ...view.children.flatMap(child => flattenViews(child))]; }
调用这个函数后,得到的结果正好是你想要的:[0, 1, 2, 3, '3.1', '3.2', 4]。
原理很简单:flatMap会把每个子节点的扁平化结果(一个数组)自动展开,和当前节点的id拼接在一起,天然符合DFS先序的遍历逻辑。
那BFS呢?
如果你的需求是层级遍历(比如先根节点,再所有第一层子节点,再所有第二层子节点),那传统的队列循环方式会更直观,map/flatMap不太适合这种按层级处理的逻辑。比如BFS的实现:
function flattenBFS(view) { const result = []; const queue = [view]; while (queue.length > 0) { const current = queue.shift(); result.push(current.id); // 把当前节点的子节点加入队列末尾 queue.push(...current.children); } return result; }
这个函数返回的结果是[0, 1, 2, 3, 4, '3.1', '3.2'],和你的示例输出不同,所以显然你的需求是DFS先序,用flatMap完全没问题。
补充:如果是DOM节点怎么办?
如果是浏览器里的DOM视图层级,逻辑也是一样的,只是获取子节点的方式换成children(元素节点)或者childNodes(所有节点):
function flattenDOMNodes(node) { // 这里返回节点本身,如果需要属性就换成node.id之类的 return [node, ...Array.from(node.children).flatMap(child => flattenDOMNodes(child))]; }
总结一下:你的需求完全可以用flatMap结合递归实现,代码简洁且符合语义;如果是层级遍历的BFS,才需要用传统的队列循环方式。
内容的提问来源于stack exchange,提问作者Heuristic
相关产品推荐
相关产品推荐

