mihneadb / node-directory-tree

Convert a directory tree to a JS object.
MIT License
523 stars 106 forks source link

[New Feature] - Sort by type! #52

Closed jcs090218 closed 6 years ago

jcs090218 commented 6 years ago

Hi, I just want to request a new feature if possible. I know the plugin sort the JSON data with alphabetical order. I think it would be nice if can sort with alphabetical order plus sort it with file type. :D

Thx!

mihneadb commented 6 years ago

Hi, the code does nothing explicit to sort the results. The result is a tree-like object, so I'm not sure how sorting would look like. I'd suggest you implement a function to sort the returned tree. What do you think?

jcs090218 commented 6 years ago

Hmmm, interesting! I thought you sort the paths alphabetically by default because the result I get from my web application is sort in alphabetic order, so I assume that you could change the sorting algorithm to whatever you what. My bad, I can just implement this myself. I thought it would be a great idea to have some filter like this. Thanks for answering my concern! If you not planning on adding stuff like this, just close this issue it if you want!

mihneadb commented 6 years ago

It's just the way the fs module returns items. Indeed, at this point I don't think it makes sense to have this included in the lib.

Feel free to share the function you end up writing here, it might be useful to others too! Thanks!

jcs090218 commented 5 years ago

Okay, this is what I meant for sorting the either by file or by directory type.

/**
 * Sort the tree result by directory/file type.
 * @param { tree.children } tree : Tree children.
 * @param { string } type : Sort type, enter 'directory' or 'file'.
 */
function sortTreeByType(tree, type = 'directory') {
  let tarList = [];  // target list.
  let anoList = [];  // another list.

  /* Split path object into two arrays by type. */
  {
    for (let index = 0;
         index < tree.length;
         ++index)
    {
      let pathObj = tree[index];
      if (pathObj.children != null && pathObj.children.length != 0) {
        sortTreeByType(pathObj.children, type);
      }

      // Add path object by type.
      if (pathObj.type == type)
        tarList.push(pathObj);
      else
        anoList.push(pathObj);
    }
  }

  /* Copy array over. */
  {
    let resultTree = tarList.concat(anoList);

    for (let index = 0;
         index < tree.length;
         ++index)
    {
      tree[index] = resultTree[index];
    }
  }
}

The default action will sort into this.

1d
1f.txt
2d
2f.txt
3d
3f.txt
4d
4f.txt

By calling this function will sort into this.

1d
2d
3d
4d
1f.txt
2f.txt
3f.txt
4f.txt

or

1f.txt
2f.txt
3f.txt
4f.txt
1d
2d
3d
4d

P.S. f represent file, d represent directory.

Hope this helps!

Szymon-dziewonski commented 1 year ago

@jcs090218 Thank you for this snippet, it saved a lot of my time :)

This is my code after minor refactor with typing

function sortTreeByType(treeChildren: DirectoryTree['children'] = [], type = 'directory') {
  let targetArray = [];
  let restArray = [];

  for (let index = 0; index < treeChildren.length; ++index) {
    let pathObj = treeChildren[index];
    if (pathObj.children?.length) {
      sortTreeByType(pathObj.children, type);
    }

    if (pathObj.type == type) targetArray.push(pathObj);
    else restArray.push(pathObj);
  }

  let resultTree = [...targetArray, ...restArray];
  for (let index = 0; index < treeChildren.length; ++index){
    treeChildren[index] = resultTree[index];
  }

  return resultTree;
}

For future travelers, usage of this script

const sortedChildren = sortTreeByType(directoryTreeResult?.children)