Sai*_*eep 6 javascript arrays jquery json jstree
就像标题所说,我有一个目录结构,我想将其转换为兼容jsTree用法的JSON格式.所以给定列表的输出
INPUT:
./Simple Root Node
./Root Node 2
./Root Node 2/Child 1
./Root Node 2/Child 2
Run Code Online (Sandbox Code Playgroud)
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" },
]
Run Code Online (Sandbox Code Playgroud)
我的方法:
目前,我从输入中获取每一行.说./Root Node 2/Child 1,然后我模式匹配第一个文件夹,创建一个像这样的数组{ "id" : "ajson2", "parent" : "#", "text" : "Root node 2" }.然后递归去下一个删除第一个文件夹.然后,创建网络数组为{ "id" : "ajson4", "parent" : "ajson2", "text" : "Child 2" }.
我为输入中的每一行执行此操作,然后使用我在http://jsfiddle.net/bsw5s60j/8/中的唯一数组函数来删除所有创建的重复数组.例如,{ "id" : "ajson2", "parent" : "#", "text" : "Root node 2" }将创建两次.一次经过第3行然后第4行.
很明显,这个代码效率很低.如果我有大约1.3K目录,那么假设每个目录有4个子目录,我们有5.2K数组,必须检查重复.
这造成了一个hge问题.有没有其他有效的方法,我可以twaek这段代码?
小提琴:(仅因为文件webkit属性而与Chrome一起使用) http://jsfiddle.net/bsw5s60j/8/
使用Javascript
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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
HTML
<input type="file" id="files" name="files[]" multiple webkitdirectory />
<div id="tree"></div>
Run Code Online (Sandbox Code Playgroud)
任何改变或建议都会非常有帮助!谢谢
这是一个简单的算法,使用从文件路径到其 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;
Run Code Online (Sandbox Code Playgroud)
您可以这样使用它进行动态更新:
// 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
};
Run Code Online (Sandbox Code Playgroud)