Download

Loop through TArray of a struct

Dear experts,

I am trying to create a function I can use in Blueprint. Basically I want to loop through an Array and output the index and the item (name) I am pointing at (for the beginning at least).

However, the Array elements are structs and I realized that the syntax must be quite different than if it held an AActor for example.

I looked at Demystifying Soft Object References | Inside Unreal - YouTube which talks about pointers but it is all in Blueprint which does not help me much.

I have this in my .h file

	UFUNCTION(BlueprintCallable, BlueprintNativeEvent, Category = "Utils")
void ArrayReverseLoop(const TArray<FInventoryItem> &InputArray, int32 &OutputIndex, FInventoryItem &OutputItem);

virtual void ArrayReverseLoop_Implementation(const TArray<FInventoryItem> &InputArray, int32 &OutputIndex, FInventoryItem &OutputItem);

and this so far in the .cpp file

void AMyPlayerController::ArrayReverseLoop_Implementation(const TArray<FInventoryItem> 
 &InputArray, int32 &OutputIndex, FInventoryItem &OutputItem)
{
int32 &SizeOfArray = InputArray.Num;
}

I keep getting compiler errors, no matter if I dereference with * or got for the address with &. I am getting confused. Do I even need the & in front of the method variables?

Thank you for any help and best regards,
Peter

UFUNCTION(BlueprintCallable, BlueprintNativeEvent, Category = "Utils")
void RandomArrayItem(const TArray<FInventoryItem>& InputArray, int32& OutputIndex, FInventoryItem& OutputItem);

void AMyPlayerController::RandomArrayItem_Implementation(const TArray<FInventoryItem> 
 &InputArray, int32 &OutputIndex, FInventoryItem &OutputItem)
{
   const int32 SizeOfArray = InputArray.Num();

   if (SizeOfArray == 0) { return; }

   OutputIndex = FMath::RandRange(0, SizeOfArray - 1);
   OutputItem = InputArray[OutputIndex];
}

Here is a small example using your code of getting a random item from that array.

Hello KaosSpectrum,

thank you, that was very helpful. I also found this link which I am going through now:
https://www.unrealengine.com/en-US/blog/ranged-based-for-loops

I have one more question. When I use a range based for loop like:

	for (FInventoryItem Item : InputArray) {
		OutputItem = Item;
	}

I can’t access the index of the TArray, is that correct? To get access to the Index I have to use an “old” for loop like:

	for (int32 ItemIndex = 0; ItemIndex < InputArray.Num(); ItemIndex++)
	{
		OutputIndex = ItemIndex;
	}

Thanks again, Peter

You are creating copies when you do that.
You should only loop by value when it’s primitive types like int, float, size_t;

For compound types use immutable labels:

for (const FInventoryItem &Item : InputArray) {

You can still used ranged-for loops and get an index, granted it requires an extra bit of code.

int32 Index = INDEX_NONE;
for (const FItem& Item : Items)
{
    Index++;
   //WhateverHere
}

or you can use traditional for loop

for (int32 I = 0; I < Items.Num(); ++i)
{
  Items[i];
}

Loops are pretty simple.

Hello BrUnO_XaVIeR,

Thank you for your help with this. I am coming from a java background and I have to
get used to pass by value and pass by reference in C++

I have to be careful with that.

Best regards, Peter

Hello KaosSpectrum,

thank you. Yes, if you know how to handle them they are easy. I just have to do a few
more exercises.

The background is that I created an inventory system but whenever I remove an item, all items
with the same database ID are deleted. I think it has to do with the loop currently used vs
a reverse loop which I should be using I think.

Best regards, Peter

At least you can try Algo::IndexOfByPredicate

thank you Emaer, I will check that out. Looks like it returns an index too.