簡體   English   中英

如何對文件夾樹進行排序

[英]How to sort tree of folders

我有一疊平面樹。 該樹具有以下屬性:id,parent_id,name。

我將這棵樹存儲在一個簡單的數組中。 問題是該數組未排序。

我數組的一個元素是這樣的簡單對象:

var obj = { id: 1, parent_id: null, name: "Folder" }

我想對它進行排序,以便能夠看到類似以下內容的東西:

Folder1
  Sub_folder1
    Sub_sub_folder1
  Sub_folder2
    Sub_sub_folder2

所以,一個...我不想使用遞歸,也不知道如何正確地做。

這是我的一些嘗試。 我嘗試在id中添加一個人工字段,該字段將代表集合中每個文件夾的數量,但是它不起作用。

var sort = function(list) {

  var f_map = {};
  var sorting_index = 1;
  var tree = angular.copy(list);

  for(var i = 0; i < tree.length; i++) {

    var node = tree[i];
    f_map[ node.id ]= { index: i, children: [] };

    if (node.parent_id) {
      f_map[ node.parent_id ].children.push( node.id );
    };

    var idx = 0;
    var visited = {};

    for(var key in f_map) {
      var index = f_map[key].index;
      var node = tree[index];
      if (!visited[node.id]) {
        node.nuid = idx++;
      } else {
        visited[node.id] = true;
      };
      if (f_map[key].children.length) {
        var children = f_map[key].children;
        for(var i = 0; i < children.length; i++) {
          var child_id = children[i];
          var child_idx = f_map[child_id].index;
          var child = tree[child_idx];
          child.nuid = idx++;
          visited[child.id] = true;
        };
      };
    };

    tree.sort(function(left, right) {
      return left.nuid - right.nuid;
    });

    return tree;
};

由於您將父指針表示為對父節點id的引用,因此我首先將文件夾的表示形式更改為對象表示形式:

var folders = {
    1: {parent_id: null, name: "Folder", path: null},
    ...
};

我添加了一個path字段,以便可以記住以下遞歸函數的結果以查找文件夾的完整路徑:

function path(node) {
    if (node.path !== null) return node.path;
    if (node.parent_id === null) {
        node.path = '/' + node.name;
    } else {
        node.path = path(folders[node.parent_id]) + '/' + node.name;
    }
    return node.path;
}

然后,我們可以通過首先提取要排序的字段和對該項目的引用來進行Schwartzian變換:

var keys = [];

Object.keys(folders).map(function (key) {
    var folder = folders[key];
    keys.push({path: path(folder), id: key});
});

然后我們可以對keys數組進行排序:

keys.sort(function (a, b) {
    var apath = a.path;
    var bpath = b.path;

    // probably the best way to compare folder paths..
    return apath.localeCompare(bpath);
});

最后,我們可以遍歷keys數組來按排序順序生成文件夾:

var sorted_folders = keys.map(function (item) {
    return folders[item.id];  // .name; or maybe .path; ??
});

就像sorted_folders是文件夾對象的列表一樣,但是根據注釋,您可以在此步驟中輕松提取所需的屬性。

首先,遞歸並不慢。 這是在您的武器庫中使用的好工具。 它使解決某些問題變得容易得多。

這是應該解決的算法。

1. If the graph can be a forest and not a tree
       create a new node root
       Make all roots in forest point to this root as parent
2. For every node, create an array (stack) of its children, call it c[i].
3. For each vertex v in tree
       c[v.parent].push(v)
4. u = root, i = 0
5. print u
6. while c[root] is not empty and u != root
       if c[u] is not empty
           u = pop(c[u])
           i++
           print tab i times
           print u
       if c[u] is empty and u != root
           u = u.parent
           i--

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM