【问题标题】:Transforming simple data object into array of array of objects depending on condition根据条件将简单数据对象转换为对象数组
【发布时间】:2018-10-04 11:42:00
【问题描述】:

我有一个评论/回复对象,我一直在尝试以对象数组的格式创建一个新对象,但这超出了我的技能水平,我目前只是一个学生

这是我要转换的对象:

[
    {"id":9,"comment":"This is a normal comment to the post SON","commentername":"noforget","parentID":42,"commentVotes":0,"isWhat":"comment","voteToID":null,"votername":null,"voteAmount":null},
    {"id":22,"comment":"new made comment","commentername":"noforget","parentID":42,"commentVotes":0,"isWhat":"comment","voteToID":null,"votername":null,"voteAmount":null},
    {"id":23,"comment":"just let me ","commentername":"noforget","parentID":42,"commentVotes":0,"isWhat":"comment","voteToID":null,"votername":null,"voteAmount":null},
    {"id":24,"comment":"bla bla","commentername":"noforget","parentID":42,"commentVotes":0,"isWhat":"comment","voteToID":null,"votername":null,"voteAmount":null},
    {"id":29,"comment":"another comment","commentername":"noforget","parentID":42,"commentVotes":0,"isWhat":"comment","voteToID":null,"votername":null,"voteAmount":null},
    {"id":30,"comment":"reply 12 btw","commentername":"noforget","parentID":29,"commentVotes":0,"isWhat":"reply","voteToID":null,"votername":null,"voteAmount":null},
    {"id":31,"comment":"reply  btw","commentername":"noforget","parentID":9,"commentVotes":0,"isWhat":"reply","voteToID":null,"votername":null,"voteAmount":null},
    {"id":32,"comment":"reply to reply btw","commentername":"noforget","parentID":31,"commentVotes":0,"isWhat":"reply","voteToID":null,"votername":null,"voteAmount":null}
]    

这是我希望它最终的格式:

[
    [
        {"id":9,"comment":"This is a normal comment to the post SON","commentername":"noforget","parentID":42,"commentVotes":0,"isWhat":"comment","voteToID":null,"votername":null,"voteAmount":null},
        {"id":31,"comment":"reply  btw","commentername":"noforget","parentID":9,"commentVotes":0,"isWhat":"reply","voteToID":null,"votername":null,"voteAmount":null},
        {"id":32,"comment":"reply to reply btw","commentername":"noforget","parentID":31,"commentVotes":0,"isWhat":"reply","voteToID":null,"votername":null,"voteAmount":null}
    ],
    [
        {"id":22,"comment":"new made comment","commentername":"noforget","parentID":42,"commentVotes":0,"isWhat":"comment","voteToID":null,"votername":null,"voteAmount":null}
    ],
    [
        {"id":23,"comment":"just let me ","commentername":"noforget","parentID":42,"commentVotes":0,"isWhat":"comment","voteToID":null,"votername":null,"voteAmount":null}
    ]
]

换句话说,我希望将主要评论及其所有回复(以及这些回复的回复等)放入数组中,该数组位于数组中

关于数据的几点说明,"isWhat"可以是"comment""reply",如果是评论,则表示只是对帖子的普通评论而不是回复,@987654326其中@ 是帖子的ID(您不必担心),"isWhat: reply"parentID 是它正在回复的评论的parentID

感谢您的宝贵时间!

【问题讨论】:

  • 到目前为止你有什么尝试?
  • @NicoHaase 我想可能会遍历它们,存储第一条评论的 ID,找到该 ID 的 parentID,我认为 reduce 方法是我需要的,我看了一些视频就可以了,但无法完成我所需要的。
  • 不要过度设计 :) 如果减少听起来太复杂,找到你自己的方法来解决它。我认为不需要行业级解决方案 - 自行解决并发现您的解决方案对您的学习过程具有很高的价值
  • @NicoHaase 我花了 2 天时间尝试不同的解决方案,这就是我在这里问这个的原因,我真的需要帮助哈哈
  • 那就看看Máté给出的答案吧。这有帮助吗?算法看起来没那么复杂

标签: javascript algorithm sorting recursion data-manipulation


【解决方案1】:

这里真的不需要递归;如果订购 cmets 以便父母总是先于孩子(假设这是相当安全的),则可以一次性完成。

假设comments 是您输入数组的名称:

var result = [];
var threadsById = {};

for (let comment of comments) {
    if (comment.isWhat == 'comment') {
        var thread = [];
        result.push(thread);
        threadsById[comment.id] = thread;
    }
    else {
        threadsById[comment.parentID].push(comment);
    }
}

【讨论】:

    【解决方案2】:

    您可以创建一个包含所有主要 cmets(不是回复)的对象

    {
      "9": [{"id": 9,...}],
      "22": [{"id": 22,...}],...
    

    然后获取所有回复,如果是对评论 9 的回复,则将该评论添加到对象并将回复 id 作为键添加到引用对象的对象[“9”]:

    {
      "9": [{"id": 9,...},"id":31,..reply to 9}],
      "22": [{"id": 22,...}],
      "31": (reference to "9")
    

    如果找不到 parentID 则说明该评论嵌套太深,其父项尚未处理,请将评论添加到需要处理的项中,然后转到下一项。

    不断重复,直到没有剩余需要处理的项目。

    代码可能如下所示:

    const comments = [
      {"id":32,"comment":"reply to reply btw","commentername":"noforget","parentID":31,"commentVotes":0,"isWhat":"reply","voteToID":null,"votername":null,"voteAmount":null},
      {"id":9,"comment":"This is a normal comment to the post SON","commentername":"noforget","parentID":42,"commentVotes":0,"isWhat":"comment","voteToID":null,"votername":null,"voteAmount":null},
      {"id":22,"comment":"new made comment","commentername":"noforget","parentID":42,"commentVotes":0,"isWhat":"comment","voteToID":null,"votername":null,"voteAmount":null},
      {"id":23,"comment":"just let me ","commentername":"noforget","parentID":42,"commentVotes":0,"isWhat":"comment","voteToID":null,"votername":null,"voteAmount":null},
      {"id":24,"comment":"bla bla","commentername":"noforget","parentID":42,"commentVotes":0,"isWhat":"comment","voteToID":null,"votername":null,"voteAmount":null},
      {"id":29,"comment":"another comment","commentername":"noforget","parentID":42,"commentVotes":0,"isWhat":"comment","voteToID":null,"votername":null,"voteAmount":null},
      {"id":30,"comment":"reply 12 btw","commentername":"noforget","parentID":29,"commentVotes":0,"isWhat":"reply","voteToID":null,"votername":null,"voteAmount":null},
      {"id":31,"comment":"reply  btw","commentername":"noforget","parentID":9,"commentVotes":0,"isWhat":"reply","voteToID":null,"votername":null,"voteAmount":null}
    ];
    
    const groupComments = comments => {
      const recur = (o,comments)=>{
        if(comments.length===0){
          return o;
        }
        const [newO,commentsLeft] = comments.reduce(
          ([o,notProcessed],comment)=>{
            if(o[comment.parentID]){//this comment is a reply to a processed comment
              o[comment.parentID].push(comment);//add this comment to array of the thread
              //add this comment id as someone may replied to it so that other comment
              //  has parentID of this comment id. the thread of this comment is the same
              //  as the thread of it's parent or parents parents parent
              o[comment.id]=o[comment.parentID];
              return [o,notProcessed];
            }
            //current comment has a parentID that is not processed yet, this could be
            //  because it's nested several levels, add comment to notProcessed
            return [o,notProcessed.concat(comment)];
          },
          [o,[]]
        );
        return recur(newO,commentsLeft);
      }
      const grouped = recur(
        comments.reduce(
          (o,comment)=>{//create an object where keys are the id's of comments that are not replies
            if(!(comment.isWhat==="comment")){
              return o;
            }
            o[comment.id]=o[comment.id] || [];
            o[comment.id].push(comment);
            return o;
          },
          {}
        ),
        comments.filter(c=>c.isWhat!=="comment")//only the replies
      );
      return comments.filter(c=>c.isWhat==="comment")//each comment that is not a reply
      .map(x=>x.id)//take the id of comment that is not a reply
      .reduce(
        (all,key)=>all.concat([grouped[key]]),//add to the array the o[mainComment.id]
        []
      );
    }
    
    console.log(
      groupComments(comments)
      //this part is to map to only id and parentid for simpler output
      .map(
        comments=>comments.map(
          ({id,parentID})=>({id,parentID})
        )
      )
    );

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-05-03
      • 2021-12-03
      • 2022-06-24
      • 2019-02-12
      • 1970-01-01
      • 2021-06-21
      相关资源
      最近更新 更多