我有如下数据结构:
Task(id,name,subTasks[Task])
但问题是subTasks可以包含具有另一个子任务的任务。这可以像这样非常深:
Task1 Contains SubTask1
SubTask1 contains it's sub tasks
你可以理解这可以深入人心。
我可以从数据库表中检索这些数据。但是如何将其存储在java脚本的数据结构中。在不知道深度的情况下使用for循环是无用的而不是优雅的方式。什么是最好的数据结构和数据遍历方式?
答案 0 :(得分:0)
如果要将任意嵌套的数据结构传输到某些其他程序(可能用其他语言编写),JSON格式是一种很好的格式,可以很容易地读取或写入JavaScript - 请参阅JSON objects in JavaScript。 但如果你要在一个JavaScript程序中完全内部地创建和使用这样的结构,则不需要JSON。
遍历任意嵌套数据结构的一般技术是recursion。 (有些人声称“递归”是关于编程学习的两个最重要的事情之一,即使在90%的编写代码中不需要它们 - Spolsky,Tim Bray,Jeff Atwood,Wenham,Sooriamurthi等。 )
有很多stackoverflow问题讨论recursion in JavaScript。 如果您阅读其中的一些,编写一些代码,测试它,然后发布一小段代码,您将获得很多更好的答案 - 它不一定非常完美。
// 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;
};
};
答案 1 :(得分:0)
程序员经常试图强制数据适应严格的层次结构, 嵌套数据结构。 ( DOM manipulation and Javascript Data Structures: Flat or Structured?, Hierarchy Considered Harmful等)
但是,如果没有纯层次结构,非嵌套结构会更好。 有时即使你有一个纯粹的层次结构,它们也能更好地工作 - 例如,当你想要在不遍历整个结构的情况下查找事物时。 例如, “哪些任务取决于名为'旋转股票'的子任务?”
也许众多alternatives to hierarchy中的一个 在你的情况下可能会更好。 例如,关联数组:
<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>