0

我有一个如下的数据结构:

Task(id,name,subTasks[Task])

但问题是子任务可以包含具有另一个子任务的任务。这可以像这样运行到很深:

Task1 Contains SubTask1

SubTask1 contains it's sub tasks

你可以理解这可以运行到很深。

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

4

2 回答 2

0

All too often, programmers try to force the data to fit into a strict hierarchy, with nested data structures. ( DOM manipulation and Javascript Data Structures: Flat or Structured? , Hierarchy Considered Harmful, etc. )

However, non-nested structures are better when you don't have a pure hierarchy. Sometimes they work better even when you do have a pure hierarchy -- such as when you want to look up things without traversing the entire structure. For example, "What tasks depend on the sub-task named 'rotate stock' ?"

Perhaps one of the many alternatives to hierarchy might work better in your case. For example, an associative array:

<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>
于 2013-09-09T15:08:46.900 回答
0

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

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

有许多讨论JavaScript 递归的stackoverflow 问题。如果您阅读其中的一些,编写一点代码,测试它,然后发布一小段代码,您会得到更好的答案——它不一定是完美的。

// 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;
    };
};
于 2013-09-07T16:19:20.213 回答