Search code examples
javascriptmongoosenotation

JS: dot notation to nested object


i struggle with this simple function. My goal is it to parse a dot notated string to a nested object.

An array of this:

["image", "groups", "groups.tasks", "groups.image"]

Should me give this:

[{
        path: "image",
        populate: []
    }, {
        path: "groups",
        populate: [{
                path: "tasks",
                populate: []
            }, {
                path: "image",
                populate: []
            }]
    }]

My code so far:

let populate = [];
const query = ["image", "groups", "groups.tasks", "groups.image"];


function parse(str, arr) {


	let c = str.split(".");
	let p = c.shift();

	console.log(c)

	let entry = {
		path: p,
		populate: []
	};


	if (c.length > 0) {

		console.log("Add to '%s'", p, c)
		parse(c.join("."), entry.populate);

	} else {

		arr.push(entry);

	}


}


query.forEach(function (str, index) {

	parse(str, populate);

});

console.log(populate)

All i get is the parent array, no childs:

[ { path: 'image', populate: [] },
  { path: 'groups', populate: [] } ]

I want to use it in a RESTful API where i can populate over nested mongoose documents. The populate array pass i then to the ".populate(...)" function in my express route

e.g:

GET /api/computer?populate=image,groups,group.tasks

There should be no limitation on the deep of nested objects.

By my reaseaches i found this awnser: How transform string dot notation to nested object? But im not sure how to modify it to reach my goal.


Solution

  • You could reduce the array by reducing the splitted path strings.

    var array = ["image", "groups", "groups.tasks", "groups.image"],
        result = array.reduce((r, s) => {
            s.split('.').reduce((a, path) => {
                var object = a.find(o => o.path === path);
                if (!object) {
                    a.push(object = { path, populate: [] });
                }
                return object.populate;
            }, r);
            return r;
        }, []);
        
    console.log(result);
    .as-console-wrapper { max-height: 100% !important; top: 0; }