使用JavaScript从数据库中检索深层数据结构

使用JavaScript从数据库中检索深层数据结构,javascript,data-structures,Javascript,Data Structures,我的数据结构如下: Task(id,name,subTasks[Task]) 但问题是子任务可以包含具有其他子任务的任务。这可以延伸到非常深的地方,如下所示: Task1 Contains SubTask1 SubTask1 contains it's sub tasks 你可以理解,这可以深入到很深的层面 我可以从数据库表中检索这些数据。但是如何将其存储在java脚本的数据结构中呢。在不知道深度的情况下使用for循环是无用的,也不是一种优雅的方式。最好的数据结构和数据遍历方式是什么?如果

我的数据结构如下:

Task(id,name,subTasks[Task])
但问题是子任务可以包含具有其他子任务的任务。这可以延伸到非常深的地方,如下所示:

Task1 Contains SubTask1

SubTask1 contains it's sub tasks
你可以理解,这可以深入到很深的层面


我可以从数据库表中检索这些数据。但是如何将其存储在java脚本的数据结构中呢。在不知道深度的情况下使用for循环是无用的,也不是一种优雅的方式。最好的数据结构和数据遍历方式是什么?

如果您想在其他程序之间传输任意嵌套的数据结构(可能是用其他语言编写的),JSON格式是一种很好的格式,可以轻松地用JavaScript读写——请参阅。 但是,如果要在单个JavaScript程序中完全在内部创建和使用此类结构,就不需要JSON

遍历任意嵌套数据结构的一般技术是。 (有些人声称“递归”是编程中最重要的两件事之一,尽管90%的书面代码都不需要它们 --,等等。 )

有许多问题需要讨论。 如果你读了其中的一些,写了一点代码,测试了它,然后发布了一小段代码,你会得到更好的答案——它不一定是完美的

// define the "Task" class
function Task(id, name, depth){
    this.id = id;
    this.name = name;
    this.depth = depth;
    this.subTask = []; // Use "[]" rather than "{}" so it works with "forEach".
    this.stringify_name_and_all_subtasks = function(depth){
        var return_string = this.depth + ":" + this.name + " ";
        // If "forEach" doesn't work for you,
        // use the "Compatibility" code in
        // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach
        this.subTask.forEach( function(entry){
            return_string += entry.stringify_name_and_all_subtasks(depth);
        });
        return return_string;
    };
};

程序员常常试图迫使数据符合严格的层次结构, 使用嵌套的数据结构。( , (等)

但是,如果没有纯层次结构,则非嵌套结构更好。 有时,即使你有一个纯粹的层次结构,它们也能更好地工作-- 例如,当您希望在不遍历整个结构的情况下查找内容时。 例如 “哪些任务依赖于名为“轮换库存”的子任务?”

也许是其中之一 对你来说可能会更好。 例如,关联数组:

<script>
"use strict";
// global task list
var tasklist_by_id = [];
var task_name_to_id = {};

// add a new task to global tasklist
function add_task(id, name, supertaskid){
    tasklist_by_id[ id ] = {"id":id, "name":name, "supertaskid":supertaskid};
    /* in other words,
    var new_task = {};
    new_task.id = id;
    new_task.name = name;
    new_task.supertaskid = supertaskid;
    tasklist_by_id[ id ] = new_task;
    */
    task_name_to_id[ name ] = id;
};

function ancestors_of( task_id ){
    if( task_id ){
        var my_name =  tasklist_by_id[ task_id ].name;
        var my_supertaskid = tasklist_by_id[task_id].supertaskid;
        var my_ancestors = ancestors_of( my_supertaskid );
        var ancestor_string = " -- " + my_name + my_ancestors;
        return ancestor_string;
    }else{
        return ".";
    };
};

function test(){
    add_task( 1, "Main task #1", 0 );
    add_task( 2, "Subtask 1", task_name_to_id[ "Main task #1" ] );
    add_task( 3, "Sub-subtask 1", task_name_to_id[ "Subtask 1" ] );
    add_task( 4, "Another Subtask of Main task 1", task_name_to_id[ "Main task #1" ] );
add_task( 5, "Sub-sub-subtask 1", task_name_to_id[ "Sub-subtask 1" ] );
    add_task( 6, "rotate_stock", task_name_to_id["Sub-sub-subtask 1" ])

    // What task is the parent task(s) of "rotate_stock" ?

    var some_task_name = "rotate_stock";
    var some_task_id = task_name_to_id[some_task_name];
    var ancestors = ancestors_of( some_task_id );

    alert("The ancestry line of " + some_task_name + " is " + ancestors);
}

test();
</script>

“严格使用”;
//全局任务列表
var tasklist_by_id=[];
var task_name_to_id={};
//将新任务添加到全局任务列表
函数添加任务(id、名称、supertaskid){
任务列表由_id[id]={“id”:id,“name”:name,“supertaskid”:supertaskid};
/*换句话说,,
var new_task={};
new_task.id=id;
new_task.name=名称;
new_task.supertaskid=supertaskid;
任务列表按任务id[id]=新任务;
*/
任务名称到id[名称]=id;
};
功能(任务id){
如果(任务id){
var my_name=tasklist_by_id[task_id].name;
var my_supertaskid=tasklist_by_id[task_id].supertaskid;
var my_祖先=的祖先(my_supertaskid);
var ANCENTER_string=“-->+我的名字+我的祖先;
返回字符串;
}否则{
“返回”;
};
};
功能测试(){
添加#u任务(1,“主任务#1”,0);
将任务(2,“子任务1”,任务名称添加到任务id[“主任务1”);
将任务(3,“子任务1”,任务名称添加到任务id[“子任务1”);
添加_任务(4,“主任务1的另一个子任务”,任务名称_到_id[“主任务1”]);
添加任务(5,“子任务1”,任务名称添加到任务id[“子任务1”);
添加任务(6,“轮换库存”,任务名称添加到任务id[“子任务1”])
//“轮换库存”的父任务是什么?
var some_task_name=“轮换库存”;
var some_task_id=任务名称到任务id[任务名称];
var祖先=祖先(某些任务id);
警报(“某个任务名+的祖先行是”+祖先);
}
test();

只需将它们存储为json对象,它们的深度可以达到您想要的深度。可能重复