Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Order nested JSON by property using NodeJS

Say I have a directory structure like this:

root
|_ .git
|_ .sass-cache
|_ css
|  |_ scss
|  |  |_ modules
|  |  |  |_ a-module.scss
|  |  |  |_ ...
|  |  |_ partials
|  |  |  |_ a-partial.scss
|  |  |  |_ ...
|  |  |_ main.scss
|  |_ main.css
|  |_ main.css.map

...

|_ .bowerrc
|_ .gitignore
|_ app.js
|_ bower.json
|_ Gruntfile.js
|_ index.html
|_ package.json
|_ README.md

I am using the following code to generate JSON of this structure but it doesn't yet maintain the ordering I'd like as shown above with folders being positioned at the top of the list (in alphabetical order) and the files being positioned at the bottom of the list (also in alphabetical order).

var fs = require('fs');
var path = require('path');

function getTree(filepath) {

    filepath = path.normalize(filepath);

    var stats = fs.lstatSync(filepath);
    var info = {
        path: filepath,
        name: path.basename(filepath)
    };

    if (stats.isDirectory()) {
        info.type = "directory";
        info.children = fs.readdirSync(filepath).map(function(child) {
            return getTree(path.join(filepath, child));
        });
    } else {
        info.type = "file";
    }
    return info;
}

exports.getTree = getTree;

(Modified from this answer)

This spits out JSON in the following format:

{
    path: '/absolute/path/to/directory',
    name: 'name-of-dir',
    type: 'directory',
    children:
        [
            {
                path: '/absolute/path/to/file',
                name: 'name-of-file',
                type: 'file',
            },
            {
                path: '/absolute/path/to/directory',
                name: 'name-of-dir',
                type: 'directory',
                children:
                    [
                        {
                            ...
                        }
                    ]
            }
        ]
}

I'd like to know how best to go about altering my existing code to sort the children arrays to replicate the directory structure order. The check should use the name and type properties to determine its location in the resultant JSON.

Many thanks

like image 625
Peter Butcher Avatar asked May 24 '26 00:05

Peter Butcher


1 Answers

Use Array.prototype.sort:

    info.children = fs.readdirSync(filepath).map(function(child) {
        return getTree(path.join(filepath, child));
    });

    info.children.sort( function(a,b) {
        // Directory index low file index
        if (a.type === "directory" && b.type === "file") return -1;
        if (b.type === "directory" && a.type === "file") return 1;

        return a.path.localeCompare(b.path);
    });
like image 134
stdob-- Avatar answered May 26 '26 14:05

stdob--