C++ using std::find in a map where the key is a custom class
up vote
0
down vote
favorite
I'm a C++ newbie and I've been struggling with this for the last couple of days.
I have a task where I need to create a map(unordered or multitable not allowed).
1. Key for the map has to be a class SportTeam and it should have a string country and a string sportsDiscipline.
2. The value for each key is a vector of strings.
3. After creating the map I should use STL find function to check if any of the keys have Poland as a country.
Here is how I created the map:
SportTeam team1{"USA", "Hockey"},
team2{"Poland", "Volleyball"},
team3{"France", "Running"},
team4{"China", "Swimming"},
team5{"Poland","Tennis"};
using mapVector = std::vector<std::string>;
std::map<SportTeam,mapVector> mapOfTeams;
mapOfTeams[team1].emplace_back("Team Beavers");
mapOfTeams[team2].emplace_back("Team Badgers");
mapOfTeams[team3].emplace_back("Team Snails");
mapOfTeams[team4].emplace_back("Team Doggos");
mapOfTeams[team5].emplace_back("Team Pinguins");
This is my header file:
class SportTeam {
public:
std::string country;
std::string sportsDiscipline;
SportTeam(std::string newCountry, std::string
newDiscipline) :
country{std::move(newCountry)},
sportsDiscipline{std::move(newDiscipline)}
{};
bool operator <(const SportTeam& other)const{
return country < other.country || (country ==
other.country && sportsDiscipline <
other.sportsDiscipline);
}
};
The problem is I have no idea how can I check the class members with find function. I was able to find country when accessing iterator like this
mapIt->first.country
and then comparing it in if statement in the iterator loop however I cannot replicate this with find function.
I tried following the cpp reference guide for std::find that suggests something like this:
auto search = example.find(2);
if (search != example.end()){
...}
but it doesn't work if I try it on map itself since it doesn't recognize "Poland". I tried different syntax combinations but the only way I was able to access the country member was when I tried this:
auto mapIt = mapOfTeams.begin();
auto search =
mapIt->first.country.find("Poland");
This option doesn't let me compare the result with mapOfTeam.end() as cpp reference suggests as it throws an error for != saying it's an invalid operand.
Any help will be appreciated. I spent quite a long time on stack and other forums but I wasn't able to find solution to my issue hence I decided to gather up my courage and write my first post here :)
TL;DR Key is a class with 2 members (country and sportsDiscipline). I have to use map::find function to check if country = "Poland" and I can't make it work.
c++ c++14 c++17
New contributor
|
show 1 more comment
up vote
0
down vote
favorite
I'm a C++ newbie and I've been struggling with this for the last couple of days.
I have a task where I need to create a map(unordered or multitable not allowed).
1. Key for the map has to be a class SportTeam and it should have a string country and a string sportsDiscipline.
2. The value for each key is a vector of strings.
3. After creating the map I should use STL find function to check if any of the keys have Poland as a country.
Here is how I created the map:
SportTeam team1{"USA", "Hockey"},
team2{"Poland", "Volleyball"},
team3{"France", "Running"},
team4{"China", "Swimming"},
team5{"Poland","Tennis"};
using mapVector = std::vector<std::string>;
std::map<SportTeam,mapVector> mapOfTeams;
mapOfTeams[team1].emplace_back("Team Beavers");
mapOfTeams[team2].emplace_back("Team Badgers");
mapOfTeams[team3].emplace_back("Team Snails");
mapOfTeams[team4].emplace_back("Team Doggos");
mapOfTeams[team5].emplace_back("Team Pinguins");
This is my header file:
class SportTeam {
public:
std::string country;
std::string sportsDiscipline;
SportTeam(std::string newCountry, std::string
newDiscipline) :
country{std::move(newCountry)},
sportsDiscipline{std::move(newDiscipline)}
{};
bool operator <(const SportTeam& other)const{
return country < other.country || (country ==
other.country && sportsDiscipline <
other.sportsDiscipline);
}
};
The problem is I have no idea how can I check the class members with find function. I was able to find country when accessing iterator like this
mapIt->first.country
and then comparing it in if statement in the iterator loop however I cannot replicate this with find function.
I tried following the cpp reference guide for std::find that suggests something like this:
auto search = example.find(2);
if (search != example.end()){
...}
but it doesn't work if I try it on map itself since it doesn't recognize "Poland". I tried different syntax combinations but the only way I was able to access the country member was when I tried this:
auto mapIt = mapOfTeams.begin();
auto search =
mapIt->first.country.find("Poland");
This option doesn't let me compare the result with mapOfTeam.end() as cpp reference suggests as it throws an error for != saying it's an invalid operand.
Any help will be appreciated. I spent quite a long time on stack and other forums but I wasn't able to find solution to my issue hence I decided to gather up my courage and write my first post here :)
TL;DR Key is a class with 2 members (country and sportsDiscipline). I have to use map::find function to check if country = "Poland" and I can't make it work.
c++ c++14 c++17
New contributor
example.find(SportTeam("Poland"));
- the rules for how many type construction rules c++ will search through is a bit weird.
– xaxxon
2 days ago
You are probably looking forstd::find_if
– super
2 days ago
@xaxxon I tried this mapOfTeams.find(SportTeam("Poland")) before but I got an error "no matching conversion between functional-style cast from const char[7] to SportTeam
– yedolte
2 days ago
@yedolte you forgot the second parameter to theSportTeam
constructor
– Asu
2 days ago
Use find_if map method with lamda.
– Victor Gubin
2 days ago
|
show 1 more comment
up vote
0
down vote
favorite
up vote
0
down vote
favorite
I'm a C++ newbie and I've been struggling with this for the last couple of days.
I have a task where I need to create a map(unordered or multitable not allowed).
1. Key for the map has to be a class SportTeam and it should have a string country and a string sportsDiscipline.
2. The value for each key is a vector of strings.
3. After creating the map I should use STL find function to check if any of the keys have Poland as a country.
Here is how I created the map:
SportTeam team1{"USA", "Hockey"},
team2{"Poland", "Volleyball"},
team3{"France", "Running"},
team4{"China", "Swimming"},
team5{"Poland","Tennis"};
using mapVector = std::vector<std::string>;
std::map<SportTeam,mapVector> mapOfTeams;
mapOfTeams[team1].emplace_back("Team Beavers");
mapOfTeams[team2].emplace_back("Team Badgers");
mapOfTeams[team3].emplace_back("Team Snails");
mapOfTeams[team4].emplace_back("Team Doggos");
mapOfTeams[team5].emplace_back("Team Pinguins");
This is my header file:
class SportTeam {
public:
std::string country;
std::string sportsDiscipline;
SportTeam(std::string newCountry, std::string
newDiscipline) :
country{std::move(newCountry)},
sportsDiscipline{std::move(newDiscipline)}
{};
bool operator <(const SportTeam& other)const{
return country < other.country || (country ==
other.country && sportsDiscipline <
other.sportsDiscipline);
}
};
The problem is I have no idea how can I check the class members with find function. I was able to find country when accessing iterator like this
mapIt->first.country
and then comparing it in if statement in the iterator loop however I cannot replicate this with find function.
I tried following the cpp reference guide for std::find that suggests something like this:
auto search = example.find(2);
if (search != example.end()){
...}
but it doesn't work if I try it on map itself since it doesn't recognize "Poland". I tried different syntax combinations but the only way I was able to access the country member was when I tried this:
auto mapIt = mapOfTeams.begin();
auto search =
mapIt->first.country.find("Poland");
This option doesn't let me compare the result with mapOfTeam.end() as cpp reference suggests as it throws an error for != saying it's an invalid operand.
Any help will be appreciated. I spent quite a long time on stack and other forums but I wasn't able to find solution to my issue hence I decided to gather up my courage and write my first post here :)
TL;DR Key is a class with 2 members (country and sportsDiscipline). I have to use map::find function to check if country = "Poland" and I can't make it work.
c++ c++14 c++17
New contributor
I'm a C++ newbie and I've been struggling with this for the last couple of days.
I have a task where I need to create a map(unordered or multitable not allowed).
1. Key for the map has to be a class SportTeam and it should have a string country and a string sportsDiscipline.
2. The value for each key is a vector of strings.
3. After creating the map I should use STL find function to check if any of the keys have Poland as a country.
Here is how I created the map:
SportTeam team1{"USA", "Hockey"},
team2{"Poland", "Volleyball"},
team3{"France", "Running"},
team4{"China", "Swimming"},
team5{"Poland","Tennis"};
using mapVector = std::vector<std::string>;
std::map<SportTeam,mapVector> mapOfTeams;
mapOfTeams[team1].emplace_back("Team Beavers");
mapOfTeams[team2].emplace_back("Team Badgers");
mapOfTeams[team3].emplace_back("Team Snails");
mapOfTeams[team4].emplace_back("Team Doggos");
mapOfTeams[team5].emplace_back("Team Pinguins");
This is my header file:
class SportTeam {
public:
std::string country;
std::string sportsDiscipline;
SportTeam(std::string newCountry, std::string
newDiscipline) :
country{std::move(newCountry)},
sportsDiscipline{std::move(newDiscipline)}
{};
bool operator <(const SportTeam& other)const{
return country < other.country || (country ==
other.country && sportsDiscipline <
other.sportsDiscipline);
}
};
The problem is I have no idea how can I check the class members with find function. I was able to find country when accessing iterator like this
mapIt->first.country
and then comparing it in if statement in the iterator loop however I cannot replicate this with find function.
I tried following the cpp reference guide for std::find that suggests something like this:
auto search = example.find(2);
if (search != example.end()){
...}
but it doesn't work if I try it on map itself since it doesn't recognize "Poland". I tried different syntax combinations but the only way I was able to access the country member was when I tried this:
auto mapIt = mapOfTeams.begin();
auto search =
mapIt->first.country.find("Poland");
This option doesn't let me compare the result with mapOfTeam.end() as cpp reference suggests as it throws an error for != saying it's an invalid operand.
Any help will be appreciated. I spent quite a long time on stack and other forums but I wasn't able to find solution to my issue hence I decided to gather up my courage and write my first post here :)
TL;DR Key is a class with 2 members (country and sportsDiscipline). I have to use map::find function to check if country = "Poland" and I can't make it work.
c++ c++14 c++17
c++ c++14 c++17
New contributor
New contributor
New contributor
asked 2 days ago
yedolte
41
41
New contributor
New contributor
example.find(SportTeam("Poland"));
- the rules for how many type construction rules c++ will search through is a bit weird.
– xaxxon
2 days ago
You are probably looking forstd::find_if
– super
2 days ago
@xaxxon I tried this mapOfTeams.find(SportTeam("Poland")) before but I got an error "no matching conversion between functional-style cast from const char[7] to SportTeam
– yedolte
2 days ago
@yedolte you forgot the second parameter to theSportTeam
constructor
– Asu
2 days ago
Use find_if map method with lamda.
– Victor Gubin
2 days ago
|
show 1 more comment
example.find(SportTeam("Poland"));
- the rules for how many type construction rules c++ will search through is a bit weird.
– xaxxon
2 days ago
You are probably looking forstd::find_if
– super
2 days ago
@xaxxon I tried this mapOfTeams.find(SportTeam("Poland")) before but I got an error "no matching conversion between functional-style cast from const char[7] to SportTeam
– yedolte
2 days ago
@yedolte you forgot the second parameter to theSportTeam
constructor
– Asu
2 days ago
Use find_if map method with lamda.
– Victor Gubin
2 days ago
example.find(SportTeam("Poland"));
- the rules for how many type construction rules c++ will search through is a bit weird.– xaxxon
2 days ago
example.find(SportTeam("Poland"));
- the rules for how many type construction rules c++ will search through is a bit weird.– xaxxon
2 days ago
You are probably looking for
std::find_if
– super
2 days ago
You are probably looking for
std::find_if
– super
2 days ago
@xaxxon I tried this mapOfTeams.find(SportTeam("Poland")) before but I got an error "no matching conversion between functional-style cast from const char[7] to SportTeam
– yedolte
2 days ago
@xaxxon I tried this mapOfTeams.find(SportTeam("Poland")) before but I got an error "no matching conversion between functional-style cast from const char[7] to SportTeam
– yedolte
2 days ago
@yedolte you forgot the second parameter to the
SportTeam
constructor– Asu
2 days ago
@yedolte you forgot the second parameter to the
SportTeam
constructor– Asu
2 days ago
Use find_if map method with lamda.
– Victor Gubin
2 days ago
Use find_if map method with lamda.
– Victor Gubin
2 days ago
|
show 1 more comment
2 Answers
2
active
oldest
votes
up vote
1
down vote
mapOfTeams.find(SportTeam("Poland", "Volleyball"));
works.
https://godbolt.org/z/K0Akq6
You have to create an object of the key type in order to compare the keys. You can't construct a SportTeam object based just on a country name, since you require both a country name and discipline.
In order to use a map/hash/dictionary/associative-array efficiently you need to make sure to key them by the thing you want to look them up by. If you want to look it up by something different (country only), then you'll need to iterate through all the entries searching the country - which is less efficient.
for(auto const & sports_team : mapOfTeams) {
if (sports_team.first.country == "Poland") {
// do whatever with match
}
}
Or as others have suggested, you can do a find_if
with a custom comparator, but that's essentially the same code as what I put above - and still not making use of the efficiency of a lookup in a map
.
To be a bit nit-picky, this is not what the question asks for. It doesn't say anything about having to specify or know thesportsDicipline
. This does however work fine if this is an option.
– super
2 days ago
@super addressed.
– xaxxon
2 days ago
thank you for the answer. It has to be by country only unfortunately. I have two objects that have country as Poland but the disciplines for them are different. The solution should return both objects. The task was to use the find function but as some posts suggest I probably got it confused with find_if
– yedolte
2 days ago
@yedolte updated answer
– xaxxon
2 days ago
You know, since C++14 astd::map
can have a transparent comparator, removing the need to create the key for comparison.
– Deduplicator
2 days ago
add a comment |
up vote
0
down vote
You need std::find_if or std::any_of where you can have UnaryPredicate (or lambda function) to give your comparison logic.
Plenty of examples are available over the internet on how to use this algorithms.
add a comment |
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
1
down vote
mapOfTeams.find(SportTeam("Poland", "Volleyball"));
works.
https://godbolt.org/z/K0Akq6
You have to create an object of the key type in order to compare the keys. You can't construct a SportTeam object based just on a country name, since you require both a country name and discipline.
In order to use a map/hash/dictionary/associative-array efficiently you need to make sure to key them by the thing you want to look them up by. If you want to look it up by something different (country only), then you'll need to iterate through all the entries searching the country - which is less efficient.
for(auto const & sports_team : mapOfTeams) {
if (sports_team.first.country == "Poland") {
// do whatever with match
}
}
Or as others have suggested, you can do a find_if
with a custom comparator, but that's essentially the same code as what I put above - and still not making use of the efficiency of a lookup in a map
.
To be a bit nit-picky, this is not what the question asks for. It doesn't say anything about having to specify or know thesportsDicipline
. This does however work fine if this is an option.
– super
2 days ago
@super addressed.
– xaxxon
2 days ago
thank you for the answer. It has to be by country only unfortunately. I have two objects that have country as Poland but the disciplines for them are different. The solution should return both objects. The task was to use the find function but as some posts suggest I probably got it confused with find_if
– yedolte
2 days ago
@yedolte updated answer
– xaxxon
2 days ago
You know, since C++14 astd::map
can have a transparent comparator, removing the need to create the key for comparison.
– Deduplicator
2 days ago
add a comment |
up vote
1
down vote
mapOfTeams.find(SportTeam("Poland", "Volleyball"));
works.
https://godbolt.org/z/K0Akq6
You have to create an object of the key type in order to compare the keys. You can't construct a SportTeam object based just on a country name, since you require both a country name and discipline.
In order to use a map/hash/dictionary/associative-array efficiently you need to make sure to key them by the thing you want to look them up by. If you want to look it up by something different (country only), then you'll need to iterate through all the entries searching the country - which is less efficient.
for(auto const & sports_team : mapOfTeams) {
if (sports_team.first.country == "Poland") {
// do whatever with match
}
}
Or as others have suggested, you can do a find_if
with a custom comparator, but that's essentially the same code as what I put above - and still not making use of the efficiency of a lookup in a map
.
To be a bit nit-picky, this is not what the question asks for. It doesn't say anything about having to specify or know thesportsDicipline
. This does however work fine if this is an option.
– super
2 days ago
@super addressed.
– xaxxon
2 days ago
thank you for the answer. It has to be by country only unfortunately. I have two objects that have country as Poland but the disciplines for them are different. The solution should return both objects. The task was to use the find function but as some posts suggest I probably got it confused with find_if
– yedolte
2 days ago
@yedolte updated answer
– xaxxon
2 days ago
You know, since C++14 astd::map
can have a transparent comparator, removing the need to create the key for comparison.
– Deduplicator
2 days ago
add a comment |
up vote
1
down vote
up vote
1
down vote
mapOfTeams.find(SportTeam("Poland", "Volleyball"));
works.
https://godbolt.org/z/K0Akq6
You have to create an object of the key type in order to compare the keys. You can't construct a SportTeam object based just on a country name, since you require both a country name and discipline.
In order to use a map/hash/dictionary/associative-array efficiently you need to make sure to key them by the thing you want to look them up by. If you want to look it up by something different (country only), then you'll need to iterate through all the entries searching the country - which is less efficient.
for(auto const & sports_team : mapOfTeams) {
if (sports_team.first.country == "Poland") {
// do whatever with match
}
}
Or as others have suggested, you can do a find_if
with a custom comparator, but that's essentially the same code as what I put above - and still not making use of the efficiency of a lookup in a map
.
mapOfTeams.find(SportTeam("Poland", "Volleyball"));
works.
https://godbolt.org/z/K0Akq6
You have to create an object of the key type in order to compare the keys. You can't construct a SportTeam object based just on a country name, since you require both a country name and discipline.
In order to use a map/hash/dictionary/associative-array efficiently you need to make sure to key them by the thing you want to look them up by. If you want to look it up by something different (country only), then you'll need to iterate through all the entries searching the country - which is less efficient.
for(auto const & sports_team : mapOfTeams) {
if (sports_team.first.country == "Poland") {
// do whatever with match
}
}
Or as others have suggested, you can do a find_if
with a custom comparator, but that's essentially the same code as what I put above - and still not making use of the efficiency of a lookup in a map
.
edited 2 days ago
answered 2 days ago
xaxxon
14.2k43058
14.2k43058
To be a bit nit-picky, this is not what the question asks for. It doesn't say anything about having to specify or know thesportsDicipline
. This does however work fine if this is an option.
– super
2 days ago
@super addressed.
– xaxxon
2 days ago
thank you for the answer. It has to be by country only unfortunately. I have two objects that have country as Poland but the disciplines for them are different. The solution should return both objects. The task was to use the find function but as some posts suggest I probably got it confused with find_if
– yedolte
2 days ago
@yedolte updated answer
– xaxxon
2 days ago
You know, since C++14 astd::map
can have a transparent comparator, removing the need to create the key for comparison.
– Deduplicator
2 days ago
add a comment |
To be a bit nit-picky, this is not what the question asks for. It doesn't say anything about having to specify or know thesportsDicipline
. This does however work fine if this is an option.
– super
2 days ago
@super addressed.
– xaxxon
2 days ago
thank you for the answer. It has to be by country only unfortunately. I have two objects that have country as Poland but the disciplines for them are different. The solution should return both objects. The task was to use the find function but as some posts suggest I probably got it confused with find_if
– yedolte
2 days ago
@yedolte updated answer
– xaxxon
2 days ago
You know, since C++14 astd::map
can have a transparent comparator, removing the need to create the key for comparison.
– Deduplicator
2 days ago
To be a bit nit-picky, this is not what the question asks for. It doesn't say anything about having to specify or know the
sportsDicipline
. This does however work fine if this is an option.– super
2 days ago
To be a bit nit-picky, this is not what the question asks for. It doesn't say anything about having to specify or know the
sportsDicipline
. This does however work fine if this is an option.– super
2 days ago
@super addressed.
– xaxxon
2 days ago
@super addressed.
– xaxxon
2 days ago
thank you for the answer. It has to be by country only unfortunately. I have two objects that have country as Poland but the disciplines for them are different. The solution should return both objects. The task was to use the find function but as some posts suggest I probably got it confused with find_if
– yedolte
2 days ago
thank you for the answer. It has to be by country only unfortunately. I have two objects that have country as Poland but the disciplines for them are different. The solution should return both objects. The task was to use the find function but as some posts suggest I probably got it confused with find_if
– yedolte
2 days ago
@yedolte updated answer
– xaxxon
2 days ago
@yedolte updated answer
– xaxxon
2 days ago
You know, since C++14 a
std::map
can have a transparent comparator, removing the need to create the key for comparison.– Deduplicator
2 days ago
You know, since C++14 a
std::map
can have a transparent comparator, removing the need to create the key for comparison.– Deduplicator
2 days ago
add a comment |
up vote
0
down vote
You need std::find_if or std::any_of where you can have UnaryPredicate (or lambda function) to give your comparison logic.
Plenty of examples are available over the internet on how to use this algorithms.
add a comment |
up vote
0
down vote
You need std::find_if or std::any_of where you can have UnaryPredicate (or lambda function) to give your comparison logic.
Plenty of examples are available over the internet on how to use this algorithms.
add a comment |
up vote
0
down vote
up vote
0
down vote
You need std::find_if or std::any_of where you can have UnaryPredicate (or lambda function) to give your comparison logic.
Plenty of examples are available over the internet on how to use this algorithms.
You need std::find_if or std::any_of where you can have UnaryPredicate (or lambda function) to give your comparison logic.
Plenty of examples are available over the internet on how to use this algorithms.
answered yesterday
Sitesh
537615
537615
add a comment |
add a comment |
yedolte is a new contributor. Be nice, and check out our Code of Conduct.
yedolte is a new contributor. Be nice, and check out our Code of Conduct.
yedolte is a new contributor. Be nice, and check out our Code of Conduct.
yedolte is a new contributor. Be nice, and check out our Code of Conduct.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53402737%2fc-using-stdfind-in-a-map-where-the-key-is-a-custom-class%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
example.find(SportTeam("Poland"));
- the rules for how many type construction rules c++ will search through is a bit weird.– xaxxon
2 days ago
You are probably looking for
std::find_if
– super
2 days ago
@xaxxon I tried this mapOfTeams.find(SportTeam("Poland")) before but I got an error "no matching conversion between functional-style cast from const char[7] to SportTeam
– yedolte
2 days ago
@yedolte you forgot the second parameter to the
SportTeam
constructor– Asu
2 days ago
Use find_if map method with lamda.
– Victor Gubin
2 days ago