【问题标题】:Remove items in an array as they are matched删除匹配的数组中的项目
【发布时间】:2012-10-04 20:00:04
【问题描述】:

我有大量线程化的 cmets。假设 cmets 如下所示:

{
  _id: [ObjectID],
  parentid: [ObjectID],
  ...
}

我有一个从数据库中检索到的所有 cmets 的大型数组:

comments = [comment1, comment2, comment3]

为了得到任意评论的回复,我有一个这样的辅助函数:

function getReplies(comment, replies) {
  return replies.filter(function(reply) {
    return reply.parentid === comment._id
  }
}

然而,当许多 cmets 已被处理(每个只有一个父级)或评论只有 1 个回复或根本没有回复(更深入评论线程)。

这是过度优化,但我想知道你们将如何解决这个问题。除非有更优雅的解决方案,否则我认为我不会更改此功能。您将如何构建此帮助程序,使其不会不必要地处理相同的评论两次?

【问题讨论】:

    标签: javascript node.js


    【解决方案1】:

    我将处理整个 cmets 列表一次,以构建从 comment._id 到回复列表的查找表。假设 comment._id 有一个合理的 toString() 表示,这样的东西应该可以工作:

    var commentIdToReplies = {};
    comments.forEach(function(comment) {
      if (comment.parentid) {
        var replies = commentIdToReplies[comment.parentid];
        if (!replies) {
          replies = [];
          commentIdToReplies[comment.parentid] = replies;
        }
        // Or just the _id if desired
        replies.push(comment);
      }
    });
    // now you can get the replies using:
    // commentIdToReplies[comment._id]
    

    如果从 commentIdToReplies 返回 undefined,则表示该评论没有回复。

    这种方法在每次都必须扫描整个列表的时间与使用更多内存来维护查找表之间进行权衡。

    【讨论】:

    • 是的,CPU 处理与内存使用的对比是我会测试以查看实际收益的。我也不是 100% 相信我应该预处理评论树,因为我只会使用评论树数组一​​次。
    • 如果您只查找单个评论的回复,那么您所写的 getReplies 就可以了。但是,我会澄清这个问题,因为不清楚什么被处理了两次。如果您想构建评论树或查找对多个 cmets 的回复,那么构建查找表很方便。
    • 好吧,我只是在寻找“胜利”。对我来说,当你有一个额外的步骤并使用更多的内存但更少的 CPU 时,这并不完全是一场胜利。但是,是的,因为我只寻找一次评论的回复,所以我的getReplies 比你的更可取,否则我实际上会按照你的方法。
    猜你喜欢
    • 1970-01-01
    • 2011-02-05
    • 2019-09-06
    • 1970-01-01
    • 1970-01-01
    • 2012-12-04
    • 1970-01-01
    • 2019-09-22
    • 1970-01-01
    相关资源
    最近更新 更多