I quickly wrote the below class for this question.
I'm looking for a way to merge addFruit()
with removeFruit()
to reduce the code.
They both use identical conditions but just different function call at the end.
My Code :
#include <iostream>
#include <string>
#include <vector>
class MyClass
{
public:
void addFruit(const std::string &str, int count)
{
if (str == "apples")
addToVec(apples, count);
else if (str == "oranges")
addToVec(oranges, count);
else if (str == "lemons")
addToVec(lemons, count);
else if (str == "melons")
addToVec(melons, count);
else if (str == "bananas")
addToVec(bananas, count);
else
std::cout << "Unknown Fruit : " << str << '\n';
}
void removeFruit(const std::string &str)
{
if (str == "apples")
removeFromVec(apples);
else if (str == "oranges")
removeFromVec(oranges);
else if (str == "lemons")
removeFromVec(lemons);
else if (str == "melons")
removeFromVec(melons);
else if (str == "bananas")
removeFromVec(bananas);
else
std::cout << "Unknown Fruit : " << str << '\n';
}
private:
void addToVec(std::vector<int> &vec, int count)
{
vec.push_back(count);
}
void removeFromVec(std::vector<int> &vec)
{
vec.pop_back();
}
std::vector<int> apples;
std::vector<int> oranges;
std::vector<int> lemons;
std::vector<int> melons;
std::vector<int> bananas;
};
Any clever way to nicely merge the two functions so I can reduce the code?
Make an additional function e.g. determineTargetVector(const std::string &str)
which returns the corresponding vector, where you want to insert/remove an element, so you have no redundant conditions. Also its nice to have only a single reponsibility for each function.
For example:
std::vector<int> *determineTargetVector(const std::string &str)
{
if (str == "apples")
return &apples;
else if (str == "oranges")
return &oranges;
else if (str == "lemons")
.
.
.
else
//something invalid, to check for in superior function
return nullptr;
}
The easiest solution might be to use a std::map
for those vectors:
std::map<std::string,std::vector<int>> fruitVecs;
The key values of the map would be "apples"
, "oranges"
, "bananas"
etc.
Thus you can easily access the corresponding vector for any operation through the map.
A code that selects the vector to be used and then perform the action can be used :
class MyClass
{
public:
void addFruit(const std::string &str, int count)
{
auto vec = selectVector(str);
if(vec != nullptr)
addToVec(*vec, count);
else
std::cout << "Unknown Fruit : " << str << '\n';
}
void removeFruit(const std::string &str)
{
auto vec = selectVector(str);
if(vec != nullptr)
removeFromVec(*vec);
else
std::cout << "Unknown Fruit : " << str << '\n';
}
private:
std::vector<int> *selectVector(const std::string &str)
{
if (str == "apples")
return &apples;
else if (str == "oranges")
return &oranges;
else if (str == "lemons")
return &lemons;
else if (str == "melons")
return &melons;
else if (str == "bananas")
return &bananas;
else
return nullptr;
}
void addToVec(std::vector<int> &vec, int count)
{
vec.push_back(count);
}
void removeFromVec(std::vector<int> &vec)
{
vec.pop_back();
}
std::vector<int> apples;
std::vector<int> oranges;
std::vector<int> lemons;
std::vector<int> melons;
std::vector<int> bananas;
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With