How to sort an array and keep track of the index

Hello, please someone teach me how to keep track of an item in an array and then the delete item when clicked, without using an arrayList.

Hey,

Could you give an exemple with a bit of code ?

Yes I have this scenario : i have two arrays, one made of 3 images, and the other made of 5 integers and a class called Trash. On my setup I am iterating these two loops.

ArrayList<Trash> trash ;
//Trash[] trash = new Trash[5];
PImage[] bottles = new PImage[3];

void setup() {
  size(640, 640);
  trash = new ArrayList<Trash>();

  for (int i = 0; i < bottles.length; i++) {
    bottles[i] = loadImage("water-bottle-"+i+".png");
  }
  for (int i = 0; i < 5; i++) {
    int index = (int(random(0, bottles.length))); 
    trash.add(new Trash(bottles[index], 120+i*100, 645, random (32, 72)));
  }
}

What i want is to click in-top of any of the images and remove it, so to start I wrote this:


  void removebottle() {
    for (int i = bottles.length-1; i>=0; i--) {
      bottles[i] = bottles[i].get();
      if (mouseX > x && mouseX < x + diamW * randomSize && mouseY > y + yay
        && mouseY < y + yay + diamH * randomSize) { 
        trash.remove(i);
      }
    }
  }

This removes the bottle array, all 3 images at once, leaving the other 2 images (made by the trash array) and when hovered over it shows an ‘out of bound’ error or a CurrentModificationException error.

Are the bottles images overlaping each other?

What do you want to do by saying that ? :

bottles[i] = bottles[i].get();

Maybe a solution is to add a break after trash.remove(i); so you only remove the first bottle.
https://processing.org/reference/break.html

Or Concurrent ModificationException? :wink: If you see that, something else is going on here too, because that means two things are trying to change the list at the same time (concurrently). What is calling removebottle()?

When i say :

bottles[i] = bottles[i].get();

I want to capture the index of the array, but then I am only capturing the index of 3 images when in truth there are 5 appearing

Hehe yes concurrent :sweat_smile:

This is calling removebottle()

void draw(){
  for (Trash part : trash) {
    part.removebottle();
  }
}

and when the Concurrent ModificationException appears it highlights this ’ for (Trash part : trash) { ’ part

What you’re actually doing is just making a needless copy of the image each time!

You cannot do this! You’re attempting to modify the list by removing items, while using an iterator over it in the loop. You could theoretically use a backwards for loop like you have in removebottle(), but I really don’t understand from your code what you’re trying to do. In particular why are you using the index in the bottle array to remove stuff from the trash list?!

how do I do it? I tried this

    for (int i = trash.size()-1; i>=0; i--) {
      if (mouseX > x && mouseX < x + diamW * randomSize && mouseY > y + yay
        && mouseY < y + yay + diamH * randomSize) { 
        trash.remove(i);
      }
    }

and it throws a Concurrent ModificationException on the

void draw(){
  for (Trash part : trash) {
    part.removebottle();
  }
}

I meant

void draw() {
  for (int i = trash.size()-1; i>=0; i--) {
    trash.get(i).removebottle();
  }
}

although that should stop the CME, it will likely crash if you remove more than one item from trash inside removebottle(). This code doesn’t actually make a lot of sense, unless there’s something key missing - you might need to go back to the drawing board with this one.

What is wrong with an ArrayList? If you have a collection of items (in your case I assume it is images) and the size of the collection can change either through deletion or adding at run-time then an ArrayList (or other list) is much better than using an array.

It is not clear what you are doing with the Trash class can you show the class here.

I am going to assume that you have 2 ArrayLists bottles to hold the current images to shows, and trash to hold the the bottles to be deleted.

So we have the lists

ArrayList<Pimage> bottles = new ArrayList<PImage>();
ArrayList<Pimage> trash = new ArrayList<PImage>();

Now we want to update the list bottles

for (PImage bottle : bottles){
  if( some_condition_to_see_if_the_bottle_should_be_deleted ){
   trash.add(bottle; // if condition true - add bottle to be deleted
  }
}
bottles.removeAll(trash); // remove unwanted bottles
trash.clear(); // clear trash can before next update

I have three images but I want 5 random images from those 3 images to appear.

I edited the post because I imagine I overwhelmed you, i made this change

ArrayList<Trash> trash  = new ArrayList<Trash>();
ArrayList<PImage> bottles = new ArrayList<PImage>();

void setup(){
  for (int i = 0; i < bottles.size(); i++) {
    bottles.add(loadImage("water-bottle-"+i+".png"));
    
  }
  for (int i = 0; i < 5; i++) {
    int index = (int(random(0, bottles.size()))); 
    trash.add(new Trash(bottles<index>, 120+i*100, 645, random (32, 72)));
  }
}
}

It is throwing this error here trash.add(new Trash(bottles<index>, 120+i*100, 645, random (32, 72))); in the coma after index

This is my class

class Trash {
  float x;
  float y;
  float speedY = 0.5;
  float randomSize;
  float offSetThis = 10; 
  float scalarThis = 3; 
  float yay;
  float diamW = int(900/400), diamH = int(800/400);

  PImage bottle;
  float upDown = 0.0;
  float speedTrash =.04; 

  //rectangel
  int rectW = width;
  int rectH = height/2;
  int rectX = 0, rectY = height/2;

  Trash(PImage tempImg, float tempX, float tempY, float tempD) {
    x = tempX;
    y = tempY;
    randomSize = tempD;
    bottle = tempImg;
  }

  void move() { 
    if (y + diamH > height) {
      speedY *= 1;
    }
    
    y--;
    
    if (y + diamH < height/2 + 40) {
      y = y + y;
      speedY *= -1;
    }
  }

  void removebottle() {
    for (int i = trash.size()-1; i>=0; i--) {
      if (mouseX > x && mouseX < x + diamW * randomSize && mouseY > y + yay
        && mouseY < y + yay + diamH * randomSize) { 
        trash.remove(i);
      }
    }
  }

  void display() {
    imageMode(CENTER);
    yay = offSetThis + sin(angle) * scalarThis;
    noTint();

    image(bottle, x, y+yay, diamW * randomSize, diamH * randomSize);
  }
}

The problem I see, honestly, is that you have your PImage variables inside your class.

You don’t need them in there!

Have one array for your images - ALL your images - and then your class only needs an index into that array from the image it wants to use. This also makes it so you don;t have duplicated images all over the place. You only need one copy of each image loaded!

PImages[] all_images = new PImage[6];

void setup(){
  size(400,400);
  all_images[0] = loadImage("bottle1.png");
  all_images[1] = loadImage("bottle2.png");
  all_images[2] = loadImage("bottle3.png");
  all_images[3] = loadImage("plasticbag.png");
  // etc

}

class Trash{
  int image_index;
  int x,y;
  Trash( int in_image_index ){
    image_index = in_image_index;
  }
  void draw(){
    image( all_images[image_index], x, y);
  }  
}
2 Likes

I want to have duplicated images. In total I want 5 images to appear out of 3 images i got. So, randomly I am making that happen

  for (int i = 0; i < 5; i++) {
    int index = (int(random(0, bottles.length)));
    trash.add(new Trash(bottles[index], 120+i*100, 645, random (32, 72)));
  }

You want to draw several time the same image at the same time but you don’t want to have duplicated image in your memory.

You should only have 5 images in memory.
The way you are building your class create a new image in memory, every time you create a new object of that class.

Instead, you should do as @TfGuy44 suggested and use an index that refers to the image that you want.

1 Like