Javascript - Remove references to my object from external arrays
I have a problem with dereferencing a Javascript object and setting it to NULL.
Here, I have a Folder implementation that supports recursive subdirectory removal. Please see my comments to understand my dilemma.
function Folder(name, DOM_rows) {
this.name = name;
this.files = [].concat(DOM_rows);
this.subdirs = [];
}
Folder.prototype.AddDir(name, DOM_rows) {
this.subdirs.push(new Folder(name, DOM_rows));
}
Folder开发者_如何学C.prototype.RemoveDir(folder) {
var stack = [folder];
while(stack.length > 0) {
var cur = stack.pop();
// do a post-order depth-first traversal, so dig to the deepest subdir:
if(cur.subdirs.length > 0) {
while(cur.subdirs.length > 0) { stack.push(cur.subdirs.pop()); }
} else {
// arrived at a leaf-level:
cur.files = null;
// now how do I delete cur from it's parent's subdirs array?
// the only way I know how is to keep a "cur.parentDir" reference,
// then find parent.subdirs[ index of cur ] and slice it out.
// How can I do the JS-equivalent of *cur = NULL?
}
}
}
Note that you don't have as big a problem as you suspect, since all subdirectories but folder
in your RemoveDir
will be deleted from their parent's subdir
by the stack.push(cur.subdirs.pop());
line
To find a subdirectory in a parent, you could make use an object-as-dictionary rather than an array for subdirs
:
function Folder(name, DOM_rows, parent) {
this.name = name;
this.parent = parent;
this.files = [].concat(DOM_rows);
this.subdirs = {};
this.subdirCount = 0;
}
Folder.prototype.AddDir = function (name, DOM_rows) {
if (this.subdirs[name]) {
return null;
}
++this.subdirCount;
return this.subdirs[name] = new Folder(name, DOM_rows, this);
}
Given a folder, you can remove the folder from the parent with:
delete folder.parent.subdirs[folder.name];
Here's a preorder version:
Folder.prototype.RemoveDir = function (folder) {
if (this.subdirs[folder.name] === folder) {
var stack = [folder];
while(stack.length > 0) {
var cur = stack.pop();
// pre-order
delete cur.files;
// if there's other processing to be done, now's the time to do it
for (subdir in cur.subdirs) {
stack.push(cur.subdirs[subdir]);
delete cur.subdirs[subdir];
}
// it's unnecessary to set subdir count, since 'cur' has been deleted
//cur.subdirCount = 0;
}
delete this.subdirs[folder.name];
--this.subdirCount;
}
}
And the recursive post-order version:
Folder.prototype.RemoveChildren = function () {
for (subdir in this.subdirs) {
this.RemoveDir(this.subdirs[subdir]);
}
}
Folder.prototype.RemoveDir = function (folder) {
if (this.subdirs[folder.name] === folder) {
folder.RemoveChildren();
folder.files = [];
delete this.subdirs[folder.name];
--this.subdirCount;
}
}
And the iterative post-order version:
Array.prototype.top = function () { return this[this.length-1]; }
Folder.prototype.RemoveDir = function (folder) {
if (this.subdirs[folder.name] === folder) {
var stack = [folder];
while(stack.length > 0) {
var cur = stack.top();
if (cur.subdirCount > 0) {
for (subdir in cur.subdirs) {
stack.push(cur.subdirs[subdir]);
delete cur.subdirs[subdir];
}
cur.subdirCount = 0;
} else {
stack.pop();
delete cur.files;
// other post-order processing
}
}
delete this.subdirs[folder.name];
}
}
Though, unless you need to take additional steps when processing deleted files & folders, a simple:
Folder.prototype.RemoveDir = function (folder) {
if (this.subdirs[folder.name] === folder) {
delete this.subdirs[folder.name];
}
}
should suffice.
Everything is javascript is passed by value, so "*cur=NULL" is not possible. You basically have the following options here
- use parentID as you suggested
- if your Folder hierarchy has a well-known root, browse from that root to find the parent object
- use something like DOM removeChild (which is called on parent), instead of removeNode (which is called on the node itself).
I was trying to do the same thing today. I've worked around it by storing the object's index as a property of the object itself.
When you add it:
myObj.ID = myArr.push(myObj);
So to remove it you
myArr[myObj.ID] = null;
I guess you solved it by now, but you could do almost the same; and it's simpler than using objects.
精彩评论