JavaScript removing elements from an array

In my situation, I am dealing with "scene" and various graphics "objects"...

Scene.prototype.objects=new Array();

Scene.prototype.add=function(obj){
  var last=this.objects.length;
  this.objects[last]=obj}

Scene.prototype.remove=function(obj){
  this.objects.splice(obj.id,1)}

Scene.prototype.advance=function(){
  for (var id in this.objects){
    var obj=this.objects[id];
    obj.id=id;
    obj.advance();
  }
}
Scene.prototype.paint=function(context){...}

As I repeatedly create and remove many objects, I am curious if there is a more efficient way to handle this in JavaScript. I know that Array.prototype.splice re-indexes the array when items are removed, but is there a better technique for adding and removing items?

In my opinion, another approach could be something like

Scene.prototype.remove=function(obj){
  delete this.objects[obj.id]; // omitting concern for this.objects.length
  delete obj; // possibly unnecessary...
}

I have yet to experiment with this alternative method...

If anyone can recommend a good book on JavaScript, I would greatly appreciate it :)

Answer №1

The approach you are taking with the delete method is not correct. This is because the variable 'objects' is actually an Array, and obj.id represents the id of the object reference stored within an element in that Array. To properly remove an element from the Array, you should use the 'splice' method. However, you need to know the index of the element in the Array. One potential solution is to keep track of the index like this:

Scene.prototype.add=function(obj){
  var last=this.objects.length;
  obj.objectsIndex = last;
  this.objects[last]=obj
}

Once you have done this, you can then remove the object like so:

Scene.prototype.remove=function(obj){
  this.objects.splice(obj.objectsIndex,1);
  //reindex the objects within the objects Array
  for (var i=0; i<this.objects.length;i++){
     this.objects[i].objectsIndex = i;
  }
}

Note: By adding the 'objects' Array to the prototype of your 'Scene' constructor, it means that it will be the same for all instances (static). Just double-check if that is the behavior you desire.

Answer №2

It appears that utilizing an array for your objects may not be necessary. Instead, consider using another object as a hash table:

(function() {

    var i = 0;

    Scene.prototype.objects = {};

    Scene.prototype.add = function(obj) {
      var id = i++;
      this.objects[id] = obj;
      obj.id = id;
    };

    Scene.prototype.remove = function(obj){
      if(obj.id in this.objects) {
          delete this.objects[obj.id];
      }
    };

    Scene.prototype.advance=function(){
      for (var id in this.objects){
        var obj=this.objects[id];
        obj.id=id;
        obj.advance();
      }
    };

    Scene.prototype.paint=function(context){...}

}());

Answer №3

I prefer to avoid utilizing new Array() and instead opt for [] (referenced on page 114 of the book 'JavaScript: The Good Parts' by Douglas Crockford ;)).

Furthermore, I have reservations about adding the objects array to the Scene prototype, as it may not function as anticipated. If your goal is to establish an Object-Oriented structure, you will need to perform some agile maneuvers in JavaScript, given its utilization of prototypal inheritance in a class-free manner.

You could consider implementing something along these lines:

var Scene = function(initial_objects) {
    this.objects = initial_objects || [];
};

Scene.prototype.add = function(obj) {
    this.objects.push(obj);
};

Scene.prototype.remove_by_index = function(index) {
    this.objects.splice(index, 1);
};

Scene.prototype.remove = function(obj) {
    var index = this.objects.indexOf(obj);
    if (index > -1) {
        this.objects.splice(index, 1);
    }
};

It may also be beneficial to review:

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Assess html code for Strings that include <% %> tags along with embedded scripts

Having a small issue with my code where I am receiving an HTML response from a web service as a java String. I need to display this String as HTML on my webpage, but the problem is that there are some script tags in the form of <% ... %> which are sh ...

Trigger an event when the menu is outside the viewport and then lock the menu to the top of the viewport

I am trying to create a menu element that remains fixed at the top of the browser viewport as the user scrolls, ensuring it is always visible. In my webpage layout, the menu sits below some text in the header initially. Once the user scrolls past the heade ...

Looking for assistance with an Angular2 post request?

I'm having an issue with a post request to obtain a token granting access to another access token. Each time I attempt to make the post request, I encounter an error stating that the access_token property is trying to read something undefined. It seem ...

Is there a way to keep track of changes in multiple dropdowns without having to create a separate JavaScript function for each one

I'm looking for a way to dynamically add more dropdowns as my website grows without having to keep adding new functions to the JavaScript code. Is there a solution for this? Currently, I can add additional functions to the JavaScript like this: ...

Using conditional statements with a series of deferred actions in jQuery

In the scenario where I have chained the $.Deferred as shown below: $.each(data, function(k, v) { promise.then(function() { return $.post(...); }).then(function(data) { if(data)... // here is the conditions return $.post(.. ...

What sets Koa apart when it comes to understanding the distinctions among await next(), return await next(), return next(), and next() in middleware?

The provided information explains the function of using 'await next()' in middleware to pause the middleware and initiate the next middleware downstream until all middlewares have completed execution. Once this happens, the process will start in ...

"Expand your list in AngularJS by automatically adding more items if the ng-repeat count is

I am struggling with this section of code. It currently shows a box with the first four linked resource images. However, I need it to display additional images if there are less than four. I tried looking for a solution, but couldn't find one. <di ...

How to invoke a custom JavaScript function within an ejs template

In an ejs file, I included my own JavaScript function which I intended to use within that file. However, the function is not working as it is declared as undefined. Below is how I declared the function inside the ejs file: //my ejs file <script> ...

I am having difficulty retrieving the JSON object that was sent by the servlet

$(document).ready(function() { var path = null; console.log('${pageContext.request.contextPath}/loadfile'); $.ajax({ dataType: "json", url: '${pageContext.request.contextPath}/loadfile&apos ...

What is the best way to access dropdown sub-menu options from a complex multi-level navigation bar

Struggling to figure out how to open my dropdown sub-menu using CSS. Hoping to make it so the user can open it by hovering over the corresponding tag. I attempted to use #lablinksDD to trigger the opening of #ddSbMenu when hovered over #menuDD with #labLin ...

Utilizing data as a substitute when creating a SearchBar using Vue3

My VueJs3 application has a search bar implemented using .filter(), and it seems to be working fine. However, when I try to pass the value from my methods to the template, an error occurs. My data becomes a proxy and I am unable to use it in that format. ...

Maintaining a JavaScript script within the local project directory and integrating it for use with Angular

I could use some assistance. I am currently working on an Angular project and making API calls (GET/PUT) to a remote server. In order to improve the performance of my application, I decided to store the necessary JS file locally in the assets folder. Init ...

Should I use a tooltip or a pop-up for the tablet version?

I'm currently working on a web application that involves presenting 10 questions, each with 3 possible answers. For each answer, I require a tooltip or popover that provides guidance. While I have attempted to use tooltips and popovers, there is an is ...

The callback function inside the .then block of a Promise.all never gets

I'm currently attempting to utilize Promise.all and map in place of the forEach loop to make the task asynchronous. All promises within the Promise.all array are executed and resolved. Here is the code snippet: loadDistances() { //return new Prom ...

The file type input is not directing to the correct folder in Internet Explorer version 9

Could someone please assist me with this problem in IE9? After I select a file to upload, then choose another one, it shows "fakepath" in IE9. See the image below for more information: https://i.sstatic.net/QsJFk.png https://i.sstatic.net/3nWRC.png htt ...

Dividing a string into sections and sending each section to a function

I'm currently facing an issue while trying to pass string objects to a function. The query string in the URL contains fields that are in a comma-separated string format with attributes of interest. I've stored the attribute names in the fields a ...

Working with the visibility of a button using JavaScript

My goal is to toggle the visibility of a button using JavaScript. Initially, on page load, the button should be hidden. function hideButton(){ var x = document.getElementById('myDIV'); x.style.display = 'none'; } The visibilit ...

Importing JS files or SDKs in Angular that are not modules

Currently, I am incorporating the Avaya SDK (which consists of 3 JS files) into my Angular project. However, when attempting to import it, I encounter an error stating that it is not recognized as a module. Any suggestions on how to resolve this issue? Th ...

What is the most effective method for declaring a constant within a WebComponent?

After receiving questions, I included more details on how I'm utilizing the constants. The main issue I am encountering is that the constants are being added to the global object, which raises concerns about potential name collisions. I created a Web ...

Display text on the screen with a customized design using JavaScript's CSS styles

I need help with printing a specific page that contains some information designed in print.css. I want to print this page, including an image, with the same style. function printContent() { var divContents = document.getElementById("terms").innerH ...