[A Little Tip] Remove elements from an array in one pass with a reverse for loop

This little tip is probably mostly for users new to blueprints (and programming) :stuck_out_tongue: but it has come to my attention that there are at least a few people around that are not aware of this, so here goes…

Lets say you have an array of… stuff… that you want to remove some elements from based on some check. For example it could be an inventory array with some expired item(s) that needs to be removed.
At first, you might have tried doing this with a For Each Loop, a *Branch *to check if the item is expired and finally, a Remove Index (or Remove Item) node.

The problem:
You might not be aware of this if you are new to programming but the problem with that approach is that every time you remove an element from an array, all elements after the removed index will be moved one position upwards.

For example:
Say we have an array of 50 elements, starting from index 0 to index 49 (array indexes start from 0).
Then while we are looping through the array elements, let’s say we want to remove the element at index 35 (let’s call it “element 35”).

The element 35 is going to removed just fine but then the elements that come next will be moved by one index… element in index 36 will now be moved in index 35, element 37 will now become element 36 and so on until we end up with an array of 49 elements (ending at index 48).

But since index 36 has been moved to index 35 (essentially taking its place) it will be skipped from the check! That means every time we remove an element, the next one will be skipped… that’s definitely not good right? it means we can remove at max, only 50% of the elements :stuck_out_tongue:

The solution:
So what is the easiest way to solve this?
Well… you could simply replace the element at index 35 with an empty element using the Set Array Elem node instead of removing it but that’s not very “clean”, is it?

How about… instead of looping the array from index 0 to 49, we start from 49 and end up at index 0 instead?
That way, when we remove element 35, we don’t care about the re-ordering of elements 36-49 to 35-48 since we have already gone through those.

A reverse for loop.

You can easily make a Blueprint Macro Library with a reverse for each loop macro.

ReverseForEachLoop
http://www.mediafire.com/convkey/3e19/5ef76yufyc7ctt6zg.jpg?size_id=7

And of course, ReverseForEachLoopWithBreak
http://www.mediafire.com/convkey/b4b1/imt0v36mfbp965ozg.jpg?size_id=7

Don’t forget to set the macro Category to:


Utilities| Array

So you can find them easier.

Enjoy :slight_smile:

3 Likes

You’re awesome, thanks!

Thank you!

Wouldn’t it be easier to always remove the first element of the array in a standard loop instead?

Thanks, solved a problem for me before I even ran into it. Google is awesome, and so are you. :slight_smile:

Hello. I creating dynamic audio player using Blueprint. Need help in final part of this task. So far I created following:

  1. List of buttons whit checkboxes (I have 2 widgets one for the scrollbox and second for child buttons with checkboxes.
  2. I created logic for checking buttons and saving states in an separate Boolean Array.
  3. Created logic for loading button checkboxes state.
  4. I created 2 new widget templates for displaying checked user result. New logic to store selected data in separate array and displaying results. All data stored in new array under it previous id using set array elem.

The final problem is when I load new array of data it also load empty id from this array. Except of empty buttons everything working well. Even cheeked Id States on a new widget on proper position. Only problem is to find solution how handle empty buttons.

be739a12d6d8c4caa337881b49bfc478bc1be571.jpeg

  1. I think the better way is to modify foreachloopwhitbreak and create logic to construct only selected checkboxes.
  2. Maybe it passable to get unchecked state of checkboxes from Boolean array and deleted unnecessary child buttons.
    What will be the better approach in my case. Perhaps someone worked on the similar task and have a solution. Thanks!!!

found another solution to wipe an array… resize it to 0.

@**TK-Master**Thanks a lot :slight_smile:

@TK-Master Thank you :slight_smile:

I noticed that there is already a macro called Reverse For Each Loop. I am on 4.24 and I presume that it now comes with the engine by default.

Big Thanks solved a big problem