简体   繁体   English

从文件目录结构创建JSON数据的有效功能?

[英]Efficient function for creating JSON data from File Directory Structure?

Like the title says, I have a directory structure, I want to convert it into a JSON format compatible for jsTree usage . 就像标题中所说的,我有一个目录结构,我想将其转换为与jsTree用法兼容的JSON格式。 So the output for a given list 所以给定列表的输出

INPUT: 输入:

./Simple Root Node
./Root Node 2
./Root Node 2/Child 1
./Root Node 2/Child 2

OUTPUT: 输出:

treeJSON = [
       { "id" : "ajson1", "parent" : "#", "text" : "Simple root node" },
       { "id" : "ajson2", "parent" : "#", "text" : "Root node 2" },
       { "id" : "ajson3", "parent" : "ajson2", "text" : "Child 1" },
       { "id" : "ajson4", "parent" : "ajson2", "text" : "Child 2" },
    ]

My Method: 我的方法:

Currently, I'm taking each line from the input. 目前,我正在从输入中提取每一行。 Say ./Root Node 2/Child 1 , then I pattern match the first folder, creating an array like { "id" : "ajson2", "parent" : "#", "text" : "Root node 2" } . ./Root Node 2/Child 1 ,然后模式匹配第一个文件夹,创建一个类似{ "id" : "ajson2", "parent" : "#", "text" : "Root node 2" }的数组。 Then go recursively for the next removing the first folder.Hence, creating the net array as { "id" : "ajson4", "parent" : "ajson2", "text" : "Child 2" } . 然后递归进行下一个删除第一个文件夹的操作。因此,将网络数组创建为{ "id" : "ajson4", "parent" : "ajson2", "text" : "Child 2" }

I do this for each line in the input and then use my unique array function as in http://jsfiddle.net/bsw5s60j/8/ to strip all the duplicate arrays which were created. 我对输入的每一行都执行此操作,然后使用http://jsfiddle.net/bsw5s60j/8/中的唯一数组函数剥离所有创建的重复数组。 For instance, { "id" : "ajson2", "parent" : "#", "text" : "Root node 2" } would be created twice. 例如, { "id" : "ajson2", "parent" : "#", "text" : "Root node 2" }将创建两次。 Once while going through the 3rd line and then the 4th line. 一次穿过第三条线,然后穿过第四条线。

Clearly, this code is HIGHLY inefficient.If I have around 1.3K directories, then assume each has 4 sub directories, we have 5.2K arrays which have to be checked for duplicates. 显然,这段代码效率很低。如果我有1.3K目录,那么假设每个目录都有4个子目录,那么我们有5.2K数组必须检查重复项。

This is creating a hge problem. 这造成了一个巨大的问题。 Is there any other efficient way I can twaek this code? 还有其他有效的方法可以修改此代码吗?

Fiddle: (Works with Chrome Only because of the file webkit attribute) http://jsfiddle.net/bsw5s60j/8/ 小提琴:(仅因文件webkit属性而与Chrome配合使用) http://jsfiddle.net/bsw5s60j/8/

Javascript Java脚本

 var input = document.getElementById('files');
 var narr = [];
 var fileICON = "file.png";

 //when browse button is pressed
 input.onchange = function (e) {
     var dummyObj = [];
     var files = e.target.files; // FileList
     for (var i = 0, f; f = files[i]; ++i) {
         var fname = './' + files[i].webkitRelativePath;
         narr = $.merge(dummyObj, (cat(fname)));
     }

     treeJSON = narr.getUnique(); // getting the JSON tree after processing input
     console.log(JSON.stringify(treeJSON));

     //creating the tree using jstree

     $('#tree')
         .jstree({
         'core': {
             'check_callback': true,
                 'data': function (node, cb) {
                 cb.call(this, treeJSON);
             }
         }
     });
     var tree = $('#tree').jstree(true);
     tree.refresh();
 };

 //get unqiue array function
 Array.prototype.getUnique = function () {
     var o = {}, a = [];
     for (var i = 0, l = this.length; i < l; ++i) {
         if (o.hasOwnProperty(JSON.stringify(this[i]))) {
             continue;
         }
         a.push(this[i]);
         o[JSON.stringify(this[i])] = 1;
     }
     return a;
 };

 // categorizing function which converts each ./Files/Root/File.jpg to a JSON

 var objArr = [];
 var folderArr = [];

 function cat(a) {
     if (!a.match(/\/(.+?)\//)) {
         var dummyObj = {};
         var fname = a.match(/\/(.*)/)[1];
         dummyObj.id = fname;
         dummyObj.text = fname;
         if (folderArr === undefined || folderArr.length == 0) {
             dummyObj.parent = '#';
         } else {
             dummyObj.parent = folderArr[(folderArr.length) - 1];
             dummyObj.icon = fileICON; // add extention and icon support
         }
         objArr.push(dummyObj);
         return objArr;
     } else {
         if (a.charAt(0) == '.') {
             var dummyObj = {};
             var dir1 = a.match(/^.*?\/(.*?)\//)[1];
             dummyObj.id = dir1;
             dummyObj.text = dir1;
             dummyObj.parent = '#';
             dummyObj.state = {
                 'opened': true,
                     'selected': true
             }; // not working
             folderArr.push(dir1);
             objArr.push(dummyObj);
             var remStr = a.replace(/^[^\/]*\/[^\/]+/, '');
             cat(remStr);
             return objArr;
         } else {
             var dummyObj = {};
             var dir1 = a.match(/^.*?\/(.*?)\//)[1];
             dummyObj.id = dir1;
             dummyObj.text = dir1;
             dummyObj.parent = folderArr[(folderArr.length) - 1];
             folderArr.push(dir1);
             objArr.push(dummyObj);
             var remStr = a.replace(/^[^\/]*\/[^\/]+/, '');
             cat(remStr);
             return objArr;
         }
     }
 }

HTML 的HTML

    <input type="file" id="files" name="files[]" multiple webkitdirectory />
<div id="tree"></div>

Any changes or suggestions would be greatly helpful! 任何更改或建议将大有帮助! Thanks 谢谢

Here is a simple algorithm that should do quite efficiently, using a map from filepaths to their ids: 这是一个简单的算法,应该使用文件路径到其ID的映射来高效地完成工作:

var idcount = 0;
var treeJSON = [];
var idmap = {};
function add(dirs) {
    if (!dirs.length) return "#";
    var name = dirs.join("/");
    if (name in idmap)
        return idmap[name];
    var dir = dirs.pop();
    var parent = add(dirs);
    var id = "ajson" + ++idcount;
    treeJSON.push({id: id, parent: parent, text: dir});
    return idmap[name] = id;
}

var files = e.target.files; // FileList
for (var i=0; i<files.length; ++i) {
    var name = files[i].webkitRelativePath;
    add(name.split("/"));
}
return treeJSON;

( updated jsfiddle demo ) 更新了jsfiddle演示

This is how you might use it for dynamic updates: 这是您可以如何使用它进行动态更新:

// initalise JStree here

var idcount = 0;
var treeJSON = [];
var idmap = {};
function add(dirs, isfolder) {
    if (!dirs.length) return "#";
    var name = dirs.join("/");
    if (name in idmap) {
        if (isfolder && idmap[name].icon)
            delete idmap[name].icon;
        return idmap[name];
    }
    var dir = dirs.pop();
    var parent = add(dirs, true);
    var id = "ajson" + ++idcount;
    var item = {id: id, parent: parent, text: dir}

    if (parent == "#")
        item.state = {opened:true, selected:true};
    if (!isfolder && dir.indexOf(".") > 0)
        item.icon = fileICON;

    treeJSON.push(item);
    return idmap[name] = id;
}

input.onchange = function(e) {
    var files = e.target.files; // FileList
    for (var i=0; i<files.length; ++i) {
        var name = files[i].webkitRelativePath;
        add(name.split("/"), false);
    }
    // refresh JStree
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM