简体   繁体   中英

recursively restructure object javascript

So this is my method for getting all posts related to their corresponding topics.

const moment = require('moment');
const mongoose = require('mongoose');

mongoose.Promise = global.Promise;

const Post = require('../models/Post');

let posts = {
    getPosts: function(req, res) {
        return Post.find({ topicId: req.params._id })
            .then(function(result) {

                console.log('------------------------------------');
                console.log('Headed to the Client: ', result);
                console.log('------------------------------------');

                res.json(result);

            })
            .catch(function(error) {
                console.log('Nope! Nerd!');
                return Promise.reject(error);
            })
    }
}

the result comes out like so:

[ { _id: 58deac2223b5b92ce45bdfac,
    topicId: '58dd6f541919c541dbf9632d',
    parentId: null,
    content: '1 Post',
    author: 'Bob',
    createdAt: 2017-03-31T19:21:06.698Z,
    isAnon: false,
    __v: 0,
    comments: [],
    isArchieved: false,
    isParent: true },

  { _id: 58deac2c23b5b92ce45bdfad,
    topicId: '58dd6f541919c541dbf9632d',
    parentId: null,
    content: '2 Post',
    author: 'Bob',
    createdAt: 2017-03-31T19:21:16.622Z,
    isAnon: false,
    __v: 0,
    comments: [],
    isArchieved: false,
    isParent: true },

  { _id: 58deac3c23b5b92ce45bdfae,
    topicId: '58dd6f541919c541dbf9632d',
    parentId: null,
    content: '3 Post',
    author: 'Bob',
    createdAt: 2017-03-31T19:21:32.682Z,
    isAnon: false,
    __v: 0,
    comments: [],
    isArchieved: false,
    isParent: true },

  { _id: 58deac5e23b5b92ce45bdfaf,
    topicId: '58dd6f541919c541dbf9632d',
    parentId: '58deac3c23b5b92ce45bdfae',
    content: '1 Comment',
    author: 'Kat',
    createdAt: 2017-03-31T19:22:06.974Z,
    isAnon: false,
    __v: 0,
    comments: [],
    isArchieved: false,
    isParent: false },

  { _id: 58deac6c23b5b92ce45bdfb0,
    topicId: '58dd6f541919c541dbf9632d',
    parentId: '58deac2223b5b92ce45bdfac',
    content: '2 Comment',
    author: 'Dave',
    createdAt: 2017-03-31T19:22:20.071Z,
    isAnon: false,
    __v: 0,
    comments: [],
    isArchieved: false,
    isParent: false },

 { _id: 58deac7a23b5b92ce45bdfb1,
    topicId: '58dd6f541919c541dbf9632d',
    parentId: '58deac2c23b5b92ce45bdfad',
    content: '4 Comment',
    author: 'Bob',
    createdAt: 2017-03-31T19:22:34.865Z,
    isAnon: false,
    __v: 0,
    comments: [],
    isArchieved: false,
    isParent: false } ]

I am getting stuck because I need to modify this list after it comes out of the database to grab the posts with parentIds and push them into their corresponding parents'comments array.

so the the result actually sent to the client looks like this:

                [{
                    _id: 58deac2223b5b92ce45bdfa',
                    topicId: '58dd6f541919c541dbf9632d',
                    parentId: null,
                    content: '1 Post',
                    author: 'Bob',
                    isAnon: false,
                    __v: 0,
                    comments: [{
                        _id: 58deac6c23b5b92ce45bdfb0,
                        topicId: '58dd6f541919c541dbf9632d',
                        parentId: '58deac2223b5b92ce45bdfac',
                        content: '2 Comment',
                        author: 'Dave',
                        isAnon: false,
                        __v: 0,
                        comments: [],
                        isArchieved: false,
                        isParent: false
                    }],
                    isArchieved: false,
                    isParent: true
                },

                {
                    _id: 58deac2c23b5b92ce45bdfad,
                    topicId: '58dd6f541919c541dbf9632d',
                    parentId: null,
                    content: '2 Post',
                    author: 'Bob',
                    isAnon: false,
                    __v: 0,
                    comments: [{
                        _id: 58deac7a23b5b92ce45bdfb1,
                        topicId: '58dd6f541919c541dbf9632d',
                        parentId: '58deac2c23b5b92ce45bdfad',
                        content: '4 Comment',
                        author: 'Bob',
                        isAnon: false,
                        __v: 0,
                        comments: [],
                        isArchieved: false,
                        isParent: false
                    }],
                    isArchieved: false,
                    isParent: true
                },

                {
                    _id: 58deac3c23b5b92ce45bdfae,
                    topicId: '58dd6f541919c541dbf9632d',
                    parentId: null,
                    content: '3 Post',
                    author: 'Bob',
                    isAnon: false,
                    __v: 0,
                    comments: [{
                        _id: 58deac5e23b5b92ce45bdfaf,
                        topicId: '58dd6f541919c541dbf9632d',
                        parentId: '58deac3c23b5b92ce45bdfae',
                        content: '1 Comment',
                        author: 'Kat',
                        isAnon: false,
                        __v: 0,
                        comments: [],
                        isArchieved: false,
                        isParent: false
                    }],
                    isArchieved: false,
                    isParent: true
                }
            ]

I know I need to recurse through the array but I'm stumped on the logic in between. Any help would be appreciated. Thank you so much.

You could use an object for collecting all nodes and append found children to the comments property. Get the nodes with parentId === null as root noded.

This approach works for unsorted data for any depth and use a single loop to get the nested result.

 var data = [{ _id: '58deac2223b5b92ce45bdfac', topicId: '58dd6f541919c541dbf9632d', parentId: null, content: '1 Post', author: 'Bob', createdAt: '2017-03-31T19:21:06.698Z', isAnon: false, __v: 0, comments: [], isArchieved: false, isParent: true }, { _id: '58deac2c23b5b92ce45bdfad', topicId: '58dd6f541919c541dbf9632d', parentId: null, content: '2 Post', author: 'Bob', createdAt: '2017-03-31T19:21:16.622Z', isAnon: false, __v: 0, comments: [], isArchieved: false, isParent: true }, { _id: '58deac3c23b5b92ce45bdfae', topicId: '58dd6f541919c541dbf9632d', parentId: null, content: '3 Post', author: 'Bob', createdAt: '2017-03-31T19:21:32.682Z', isAnon: false, __v: 0, comments: [], isArchieved: false, isParent: true }, { _id: '58deac5e23b5b92ce45bdfaf', topicId: '58dd6f541919c541dbf9632d', parentId: '58deac3c23b5b92ce45bdfae', content: '1 Comment', author: 'Kat', createdAt: '2017-03-31T19:22:06.974Z', isAnon: false, __v: 0, comments: [], isArchieved: false, isParent: false }, { _id: '58deac6c23b5b92ce45bdfb0', topicId: '58dd6f541919c541dbf9632d', parentId: '58deac2223b5b92ce45bdfac', content: '2 Comment', author: 'Dave', createdAt: '2017-03-31T19:22:20.071Z', isAnon: false, __v: 0, comments: [], isArchieved: false, isParent: false }, { _id: '58deac7a23b5b92ce45bdfb1', topicId: '58dd6f541919c541dbf9632d', parentId: '58deac2c23b5b92ce45bdfad', content: '4 Comment', author: 'Bob', createdAt: '2017-03-31T19:22:34.865Z', isAnon: false, __v: 0, comments: [], isArchieved: false, isParent: false }], tree = function (data, root) { var r = [], o = {}; data.forEach(function (a) { a.comments = (o[a._id] && o[a._id].comments || []).concat(); o[a._id] = a; if (a.parentId === root) { r.push(a); } else { o[a.parentId] = o[a.parentId] || {}; o[a.parentId].comments = o[a.parentId].comments || []; o[a.parentId].comments.push(a); } }); return r; }(data, null); console.log(tree); 
 .as-console-wrapper { max-height: 100% !important; top: 0; } 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM