3

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

Community
  • 1
  • 1
Peter Butcher
  • 156
  • 1
  • 8

1 Answers1

2

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);
    });
stdob--
  • 28,222
  • 5
  • 58
  • 73