1

I have a class Inventory

class Inventory {
    private:
        vector<Item> items;
    public:
        void addItem(Item item) {
            items.push_back(item);
        }

        void removeItem(string n) {
            # Complete this
        }
}

And a class Item

class Item {
    private:
        string name;
        int power;
    public:
        Item(string n, int p) {
            name = n; power = p;
        }
        
        string getName(){
            return name;
        }
};

how can I remove an item from items if the name of the Item is equal to a string n?

something like:

bool matches(string name, Item item){
    if (name == item.getName()) return true;

    return false;
}

find_if(items.begin(), items.end() matches(someVariable, someObject));

TL;DR I need to remove an object from a vector if the value of a variable inside the object is equal to a variable passed to the function

steamsy
  • 104
  • 1
  • 8
  • In C++11, this is what lambdas are for. Before C++11, you will have to do more work. Whichever version of C++ you can use, your C++ textbook should have plenty of examples of accomplishing this basic, fundamental task. All C++ textbooks cover this topic. Is there anything in your textbook's explanation that's unclear to you? – Sam Varshavchik Aug 10 '20 at 01:08
  • 3
    erase-remove https://stackoverflow.com/a/347478/1766544 see also https://en.wikipedia.org/wiki/Erase%E2%80%93remove_idiom – Kenny Ostrom Aug 10 '20 at 01:11
  • what if two items have the same name? Have you considered implementing the inventory class using `unordered_map/map` – Onyambu Aug 10 '20 at 01:29

2 Answers2

1

The correct way of doing this is to use the combination of std::remove / std::remove_if and erase.

You can find the documentation in the CPP Reference here and here. In the std::remove example code, you can see also the combination of remove and erase. You can also find tons of similar examples here on SO.

std::remove_if will use a simple lambda that checks, if the item name matches the search name.

Please see:

#include <iostream>
#include <string>
#include <vector>

class Item {
private:
    std::string name;
    int power;
public:
    Item(std::string n, int p) {
        name = n; power = p;
    }

    std::string getName() {
        return name;
    }
};
class Inventory {
private:
    std::vector<Item> items;
public:
    void addItem(Item item) {
        items.push_back(item);
    }

    void removeItem(std::string n) {
        items.erase(std::remove_if(items.begin(), items.end(), [n](Item& i) { return i.getName() == n; }), items.end());
    }
};

int main() {

    Inventory inventory{};

    // Add 20 item as a demo
    for (int i{}; i < 20; ++i) inventory.addItem(Item(std::to_string(i), i));

    // Remove Item "3"
    inventory.removeItem("3");

    return 0;
}

A M
  • 14,694
  • 5
  • 19
  • 44
0

The original way as follow.

void removeItem(string n) {
    for (int i = 0; i < items.size(); ++i) {
        if (items[i].getName() == n) {
            items.erase(items.begin() + i);
            break;
        }
    }
}

Albert
  • 29
  • 1
  • 5