Remove from Array, !works all the time?

I converted this bp script to C++ and sometime it returns failed to removed items, but the item was removed but it still prints the item was not removed.

void AGameState::RemoveEquipment(AItemBase* Equipments_, bool& bRemoved)
{
	bool bEqRwmoved;
	if (Equipments.Remove(Equipments_))
	{
		bEqRwmoved = true;
		OnEquipmentChanged_Ref.Broadcast(this, Equipments_, false);
		bRemoved = bEqRwmoved;
	}
	else
	{
		print100s("Equipments Cant be Removed from the Array: @PlayerState::RemoveEquipment");
		return;
	}
	
}

If preserving the order does not matter:

bool AGameState::RemoveEquipment(AItemBase* Item)
{
  if (!Equipments.RemoveSwap(Item, false)) {
    print100s(...);
    return false;
  }
  OnEquipmentChanged_Ret.Broadcast(this, Item, false);
  return true;
}

Assuming it’s TArray<AItemBase*> and you don’t have duplicate pointers, it’s worth to use TArray<T>::RemoveSingleSwap instead.

2 Likes

I’d suggest that you first check your array, if the item you want to remove is really contained in the array. Your code actually will print “can’t be removed” and afterwards the item is not present (this does not mean, that it was removed) - so your observervation perfectly fits that situation. I’m pretty sure, your item is not in the array when you call the remove function.

Remove returns the number of items it did remove. If it reports 0, then none of these items has been in the array, otherwise this would be a serious bug in the code.

And the code could be simpler, see post by Emaer

1 Like

yes using swapremove resolved the issue, thank You Sir very much

yes thank You for the detailed information, really appreciated

Hi @Emaer, that’s really interesting.

From what my knowledge is, remove swap tries to do the removal in a more efficient manner by doing a Find for the element first, then exchanging/swapping it with the last element in the array and then just removing the last, so no shifting of a number of elements is needed to fill the gap - at the cost of not preserving the order of the array. Please correct me, if I’m wrong.

How can this way of removal work, while a simple remove function fails for the same operation? It obviously does, as Alexa says, but I just do not understand why. That’s a really interesting phenomenon, so it would be great, if you could explain a little bit.
Thank you

@herb64
Exactly. If the order of the elements does not matter then it is more efficient because it has a complexity of O(1) - always the same regardless of the number of elements in the array.

Honestly, I don’t know. Probably the problem lies elsewhere and isn’t related to Remove function. We don’t know the context of how the function is called. I can only presume that returning a value via the output parameter may be the culprit (not cleared between calls?)

2 Likes

I called in just an event by pressing 1 to add and pressing 2 to remove.