最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

null - Javascript - Remove references to my object from external arrays - Stack Overflow

programmeradmin3浏览0评论

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 ments 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.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?
      }
   }
}

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 ments 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.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?
      }
   }
}
Share asked Nov 19, 2009 at 23:13 Jeff Meatball YangJeff Meatball Yang 39.1k27 gold badges93 silver badges125 bronze badges 2
  • Any reason you're not using recursion for RemoveDir? Is there any additional processing not shown in sample that needs to be performed on files or folders when they're deleted? – outis Commented Nov 20, 2009 at 0:33
  • @outis: I just prefer iterative over recursive. It might be more space-effective to do it recursively in some cases, but I know that the breadth (number of subdirs at each level) will be small relative to the depth. And actually, my app isn't about folders and files, but it has the same structure. There are more properties to my "Folder" object that need to be processed and removed. – Jeff Meatball Yang Commented Nov 20, 2009 at 3:55
Add a ment  | 

3 Answers 3

Reset to default 4

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.

发布评论

评论列表(0)

  1. 暂无评论