Removing only a single duplicate element from a vector of objects

So I have been trying to design combat mechanics in a text based RPG project, and currently I have a player class with an inventory that is a vector of shared pointers to a base "item" class. This contains weapons, potions, and token items that only have a use in the plot. Here is an example function that I use for deleting all items from the vector with the same string attribute in the item class:

1
2
3
4
5
6
7
8
9
10
11
12
13
14

void player::remove_item_by_name(string item_name) {

	inventory.erase(
		std::remove_if(
			inventory.begin(),
			inventory.end(),
			[item_name](shared_ptr<item> it) { return it->get_item_name() == item_name; }),
		inventory.end());



}


This code for example gets used at a point in the story where the player has the option to drop all their weapons.

Now what I would like to do is to be able to pick out a set of items by name (this will be for using potions), but if there are duplicates of that item (for example a player can hold multiple shield potions) only delete ONE of those items. I have found a lot of example codes online for deleting all duplicates in a vector by using std::remove_if and sets, but nothing to only delete one element.

I thought maybe I could narrow down the items in the inventory by filtering usng the given potion name, moving those elements to the front of the vector and deleting the first element, but I'm not really sure how to implement it. Does anyone have any pointers for me to be able to do this?
Last edited on
Do you mean:
1
2
3
4
auto item = std::find_if( inventory.begin(), inventory.end(), something );
if ( item != inventory.end() ) {
  // get rid of that item
}
Yeah that's along the lines of what I mean, but as in the example code I put for deleting multiple elements, item has the function it->get_item_name() for finding a specific potion in my case. The struggle I'm having is that all shield potions for example wil share the same name, so when I use a potion I only want to delete one of a set of matching types. I'm just a bit lost for how to do that part specifically, as the inventory isn't in a set order and the player has free reign when it comes to what they choose to go in the inventory, so it won't be the same from one game to another so can't do it by index.
one of a set of matching types

The find_if returns iterator to one of those elements (if any).

The question is thus, how to write the predicate?
[X](shared_ptr<item> it) { return X does match *it; }

In your other case the "X does match Y" was written it->get_item_name() == item_name.
That is simple equality. You can have much more complex conditions, if you want.

You must know what X you will get (from the player) and what potions that should match.

Topic archived. No new replies allowed.