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

6
  • 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? Commented May 21, 2013 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. Commented May 21, 2013 at 21:09
  • 2
    if you dont want looping, u need use a dictionary or a similar hash data estructure. Commented May 21, 2013 at 21:10
  • You could keep an index I guess. Try it? Commented May 21, 2013 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. Commented May 21, 2013 at 21:10

3 Answers 3

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

Sign up to request clarification or add additional context in comments.

2 Comments

Unless you really need for it to be in an array this is the way I would do it.
@pseudosavant, yeah exactly! Thanks for the confirmation :)
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

1 Comment

FWIW Array.filter isn't supported on IE8, if that matters to the OP.
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 = "";
}

7 Comments

This definitely works if you really have to have it in an array, but does have more overhead with the hashes.
@pseudosavant you mean that manual looping will be faster than the hashing ?
@MirrorMirror, I guess pseudosavant means that using an array at all has more overhead then using hashes... right?
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.)
JSON doesn't mind plain objects at all. The only quirk is, your divIDs 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).
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.