根据条件将简单数据对象转换为对象数组的数组

时间:2018-04-24 09:17:12

标签: javascript algorithm sorting recursion data-manipulation

我有一个评论/回复对象,我一直在尝试以对象数组的数组格式创建一个新对象,但它高于我的技能水平,我现在只是一名学生

这是我要转换的对象:

[
    {"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",如果它是评论,则表示它只是正常对帖子发表评论而不是回复,parentID的帖子是ID帖子(你不应该担心),parentID "isWhat: reply" 1}}是其回复

的评论的parentID

感谢您的时间!

2 个答案:

答案 0 :(得分:1)

你真的不需要递归;如果订购评论以便父母总是在孩子面前(这是非常安全的假设),这可以一次完成。

假设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);
    }
}

答案 1 :(得分:0)

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

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

然后获取所有回复,如果它回复评论9然后将该评论添加到对象并将回复id作为关键字添加到对象引用对象[&#34; 9&#34;]:< / p>

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

如果找不到parentID,那么这意味着评论嵌套太深而且它的父级尚未处理,请将评论添加到需要处理的项目并转到下一个项目。

不断重复,直到没有剩余物品需要处理。

代码看起来像这样:

&#13;
&#13;
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})
    )
  )
);
&#13;
&#13;
&#13;