1

I want to be able to delete an object from an array without looping all the array of objects to see if the current array element has the ID of the item I want to delete.

javascript:

function CBooks() {
    this.BooksArray = [];

    this.AddBook = function(divID, sContents) {
        this.BooksArray.push(new CBook());
        pos = this.BooksArray.length - 1;
        this.BooksArray[pos].ArrayID = pos;
        this.BooksArray[pos].DivID = divID;
        this.BooksArray[pos].Contents = sContents;
    }

    this.DelBook = function(divID) {
        this.BooksArray.splice(...);
    }
}

function CBook() {
    this.ArrayID = 0;
    this.DivID = "";
    this.Contents = "";
}

I initialize the object like this:

var oBooks = new CBooks();

I add a new book like this :

oBooks.AddBook("divBook1", "blahblahblah");
//Creation of the div here
oBooks.AddBook("divBook2", "blehblehbleh");
//Creation of the div here

Now the user can click an X button in the div displaying each book, so that he can delete the book. So the X button contains:

onclick=oBooks.DelBook(this.id);

Now obviously in the DelBook(divID) function I could loop through the length of the BooksArray and see each element if it's divID is equal to the parameter and splice at that point, but I want to avoid the looping.

Is there any way to do it ?

thanks in advance

MirrorMirror
  • 186
  • 8
  • 36
  • 70
  • 4
    Why do you want to avoid the looping, is there an acute performance issue? If no: just do the looping. If yes: use some kind of hash bucket system? What did you have in mind? – Halcyon May 21 '13 at 21:07
  • I want to avoid the looping because I thought that there may be some faster method to just access that element directly with the help of javascript associative arrays. – MirrorMirror May 21 '13 at 21:09
  • 2
    if you dont want looping, u need use a dictionary or a similar hash data estructure. – levi May 21 '13 at 21:10
  • You could keep an index I guess. Try it? – Halcyon May 21 '13 at 21:10
  • This is a very common question around here. You either have to do the looping yourself, or you can use a library that does looping. Or... as @FritsvanCampen has mentioned, you could use some sort of hashing system or you could store an index in the book objects. – jahroy May 21 '13 at 21:10
  • Check it http://stackoverflow.com/questions/1208222/how-to-use-dictionary-or-hashtable-in-javascript – levi May 21 '13 at 21:11

3 Answers3

5

Something like this would work, but only if you are willing to abandon the array used for a hash.

Your code edited

function CBooks() {
  this.BooksHash = {};

  this.AddBook = function(divID, sContents) {
    var book = new CBook();
    //book.ArrayID = pos; //you don't actually need this anymore using a hash
    book.DivID = divID;
    book.Contents = sContents;
    this.BooksHash[book.DivID] = book;
  }

  this.DelBook = function(divID) {
    delete this.BooksHash[divID];
  }
}

function CBook() {
  //this.ArrayID = 0; // same here
  this.DivID = "";
  this.Contents = "";
}

Hope it helps

intuitivepixel
  • 23,302
  • 3
  • 57
  • 51
2
arr.filter(function(item){
  Return item.id != idtoremove
 });

That will loop under the covers, but uses fast native code and is easier to read. If you really want O(1) delete you'll need to use some sort of hash and will add extra overhead on creating and updating the array

Ben McCormick
  • 25,260
  • 12
  • 52
  • 71
0

I solved it like this:

function CBooks() {
    this.BooksArray = [];
    this.Hashes = {};

    this.AddBook = function(divID, sContents) {
        this.BooksArray.push(new CBook());
        pos = this.BooksArray.length - 1;
        this.BooksArray[pos].ArrayID = pos;
        this.Hashes[divID] = pos;
        this.BooksArray[pos].DivID = divID;
        this.BooksArray[pos].Contents = sContents;
    }

    this.DelBook = function(divID) {
        this.BooksArray.splice(this.Hashes[divID], 1);
    }
}

function CBook() {
    this.ArrayID = 0;
    this.DivID = "";
    this.Contents = "";
}
MirrorMirror
  • 186
  • 8
  • 36
  • 70
  • This definitely works if you really have to have it in an array, but does have more overhead with the hashes. – pseudosavant May 21 '13 at 21:32
  • @pseudosavant you mean that manual looping will be faster than the hashing ? – MirrorMirror May 21 '13 at 21:34
  • @MirrorMirror, I guess pseudosavant means that using an array at all has more overhead then using hashes... right? – intuitivepixel May 21 '13 at 21:37
  • An array pretty much has to extra overhead. Consider that removing an element from the array requires either moving all the entries after it, or modifying their indexes. That's a linear-time operation. You might save some time if the entry is near the end, but entries near the beginning will still require touching nearly every element. (It's probably in native code, so it may well be faster...but it still can't beat deleting an object property.) – cHao May 21 '13 at 21:42
  • Unless you absolutely have to have an array for some reason, i'd just stick the books directly in the hash and skip the array altogether. – cHao May 21 '13 at 21:43
  • @cHao yes true, splicing will be costly, while delete key will just empty the key to null. I will think about it. I will need to json stringify them at some point, if just sticking to hashes is fine with stringifying, I will opt for it – MirrorMirror May 21 '13 at 21:45
  • 1
    JSON doesn't mind plain objects at all. The only quirk is, your `divID`s will be in there as keys. That's easily enough fixed by creating an array of the values when you have to save (which shouldn't be near as often as you'll be looking up stuff). – cHao May 21 '13 at 21:52