根据JSON响应创建嵌套评论数组

问题描述

我想使用Hacker News Algolia APIexact query)查找注释,然后根据数据创建嵌套的JSON结构。我知道我需要使用递归,但是我不太确定该怎么做。

这是我想要的结构:

comment1
  comment2
    comment3
comment4
comment5

在JSON中:

[
  {
    "text": "eee","children": [
      {
        "text": "123","childeren": [
          {
            "text": "rew"
          }
        ]
      }
    ]
  },{
    "text": "comment4","children": []
  },{
    "text": "comment5","children": []
  }
]

问题在于API不会以上述格式返回注释。返回的注释具有属性parent_id,该属性是对其父注释的objectID的引用。因此,如果您有以下嵌套的objectID

foo
  bar
    foobar

foobar的{​​{1}}是parent_id,而bar的{​​{1}}是bar。最后,parent_id的{​​{1}}是Hacker News帖子ID,在本例中为foo

到目前为止我有什么[repl]

foo

解决方法

forEach用于遍历数组。使用map将数组转换为新数组。试试:

function getChildren(comment: Comment,allComments: Comment[]) {
  return {
    ...comment,children: allComments
      .filter(c => String(c.parent_id) === comment.objectID)
      .map(c => getChildren(c,allComments))
  };
}

...这将为您提供所需的嵌套数组。

但是我建议使用其他方法。请注意,对于每个孩子,您都要遍历整个集合。一次遍历数组以收集父/子关系会更有效:

const byParent = new Map<string,Array<Comment>>();
for (const comment of allComments) {
  let children = byParent.get(comment.parent_id);
  if (!children) {
    children = [];
    byParent.set(comment.parent_id,children);
  }
  children.push(comment);
}

现在,您可以随时执行byParent.get(comment.objectID)来获取子注释,并在必要时进行递归操作:

function getChildren(comment: Comment) {
  return {
    ...comment,children: byParent.get(comment.objectID)?.map(getChildren)
  };
}