![]() |
|
|
|||||||
![]() |
C++ - To retrieve Keys or values of a Map |
|
|
Thread Tools | Search this Thread |
|
|
#1 |
|
Dear all
I have a question. Is there any generic algorithm or solution to access the keys or values of a map? I frequently face to such problem and I usually write a function to copy the keys/values of a map into a container let say a vector. Many thanks, in advance, for your help. Saeed Amrollahi |
|
|
|
|
#2 |
|
Posts: n/a
|
Saeed Amrollahi wrote:
> Dear all > > I have a question. Is there any generic algorithm or solution to > access the keys or values > of a map? I frequently face to such problem and I usually write a > function to copy > the keys/values of a map into a container let say a vector. > > Many thanks, in advance, for your help. I've written a utility roughly like this: #include <string> #include <algorithm> #include <iostream> #include <list> #include <map> #include <iterator> namespace { template <typename T1, typename T2> const T1& take_first(const typename std::map<T1,T2>::value_type& pair) { return pair.first; } } template <typename T1, typename T2> std::list<T1> keys(const std::map<T1,T2>& in) { std::list<T1> klist(in.size()); std::transform(in.begin(), in.end(), klist.begin(), take_first<T1,T2>); return klist; } int main() { std::map<std::string, int> map; map["test"] = 0; map["test2"] = 0; const std::list<std::string>& keys = ::keys(map); std::copy(keys.begin(), keys.end(), std: return 0; } Although this isn't exactly ideal, and would be a nice place to use a lambda function in C++0x too. There's a few annoying things about this though, the function take_first has to live inside the anonymous namespace because it's not legal to write the following, which given the absence of lambda functions would be cleaner in my view: template <typename T1, typename T2> std::list<T1> keys(const std::map<T1,T2>& in) { struct { const T1& operator()(const typename std::map<T1,T2>::value_type& pair) { return pair.first; } } take_first; std::list<T1> klist(in.size()); std::transform(in.begin(), in.end(), klist.begin(), take_first); return klist; } I also never got type deduction for the function pointer argument to std::transform to work, which I kind of expected it would, although that's not exactly a problem. Alan Alan Woodland |
|
|
|
#3 |
|
Posts: n/a
|
On Nov 4, 3:05*pm, Alan Woodland <a...@aberystwyth.ac.uk> wrote:
> Saeed Amrollahi wrote: > > Dear all > > > I have a question. Is there any generic algorithm or solution to > > access the keys or values > > of a map? I frequently face to such problem and I usually write a > > function to copy > > the keys/values of a map into a container let say a vector. > > > Many thanks, in advance, for your help. > > I've written a utility roughly like this: > > #include <string> > #include <algorithm> > #include <iostream> > #include <list> > #include <map> > #include <iterator> > > namespace { > * *template <typename T1, typename T2> > * *const T1& take_first(const typename std::map<T1,T2>::value_type& pair) { > * * *return pair.first; > * *} > > } > > template <typename T1, typename T2> > std::list<T1> keys(const std::map<T1,T2>& in) { > * *std::list<T1> klist(in.size()); > * *std::transform(in.begin(), in.end(), klist.begin(), take_first<T1,T2>); > * *return klist; > > } > > int main() { > * *std::map<std::string, int> map; > * *map["test"] = 0; > * *map["test2"] = 0; > > * *const std::list<std::string>& keys = ::keys(map); > * *std::copy(keys.begin(), keys.end(), > std: > > * *return 0; > > } > > Although this isn't exactly ideal, and would be a nice place to use a > lambda function in C++0x too. > > There's a few annoying things about this though, the function take_first > has to live inside the anonymous namespace because it's not legal to > write the following, which given the absence of lambda functions would > be cleaner in my view: > > template <typename T1, typename T2> > std::list<T1> keys(const std::map<T1,T2>& in) { > * *struct { > * * *const T1& operator()(const typename std::map<T1,T2>::value_type& > pair) { > * * * *return pair.first; > * * *} > * *} take_first; > > * *std::list<T1> klist(in.size()); > * *std::transform(in.begin(), in.end(), klist.begin(), take_first); > * *return klist; > > } > > I also never got type deduction for the function pointer argument to > std::transform to work, which I kind of expected it would, although > that's not exactly a problem. > > Alan Hi Alan Thank you for your code. It is really good. It is better than my code and I definitely will use it. So, there is no pre-built generic algorithm for doing this. Thanks again, -- Saeed Amrollahi Saeed Amrollahi |
|
|
|
#4 |
|
Posts: n/a
|
On Nov 4, 4:44*am, Saeed Amrollahi <amrollahi.sa...@gmail.com> wrote:
> Dear all > > I have a question. Is there any generic algorithm or solution to > access the keys or values > of a map? I frequently face to such problem and I usually write a > function to copy > the keys/values of a map into a container let say a vector. > > Many thanks, in advance, for your help. #include <string> #include <iterator> #include <boost/foreach.hpp> #include <iostream> #include <list> #include <map> typedef std::map<std::wstring,std::wstring> MyMapType; typedef std: MyMapType MyMap; template<typename U> std::list<typename U::key_type> getKeys(U const &m) { typedef std: PairType; std::list<typename U::key_type> tempList; BOOST_FOREACH(PairType const &i,m) tempList.push_back(i.first); return tempList; } int main() { MyMap[L"one"] = L"Hello World"; MyMap[L"two"] = L"Another string"; std::list<std::wstring> myList = getKeys(MyMap); BOOST_FOREACH(std::wstring &i,myList) std::wcout << i << L"\n"; return 0; } mzdude |
|
|
|
#5 |
|
Posts: n/a
|
On Nov 5, 5:30*pm, mzdude <jsa...@cox.net> wrote:
> On Nov 4, 4:44*am, Saeed Amrollahi <amrollahi.sa...@gmail.com> wrote: > > > Dear all > > > I have a question. Is there any generic algorithm or solution to > > access the keys or values > > of a map? I frequently face to such problem and I usually write a > > function to copy > > the keys/values of a map into a container let say a vector. > > > Many thanks, in advance, for your help. > > #include <string> > #include <iterator> > #include <boost/foreach.hpp> > #include <iostream> > #include <list> > #include <map> > > typedef std::map<std::wstring,std::wstring> MyMapType; > typedef std: > > MyMapType MyMap; > > template<typename U> > std::list<typename U::key_type> getKeys(U const &m) > { > * *typedef std: > PairType; > > * *std::list<typename U::key_type> tempList; > * *BOOST_FOREACH(PairType const &i,m) > * * * tempList.push_back(i.first); > * *return tempList; > > } > > int main() > { > * *MyMap[L"one"] = L"Hello World"; > * *MyMap[L"two"] = L"Another string"; > > * *std::list<std::wstring> myList = getKeys(MyMap); > > * *BOOST_FOREACH(std::wstring &i,myList) > * * * std::wcout << i << L"\n"; > > * *return 0; > > > > }- Hide quoted text - > > - Show quoted text - Thank you. Saeed Amrollahi |
|
|
|
#6 |
|
Posts: n/a
|
On Nov 4, 1:44*am, Saeed Amrollahi <amrollahi.sa...@gmail.com> wrote:
> Dear all > > I have a question. Is there any generic algorithm or solution to > access the keys or values of a map? I frequently face to such > problem and I usually write a function to copy the keys/values > of a map into a container let say a vector. > > Many thanks, in advance, for your help. What exactly do you want? You just want to access a map's current contents? Then iterate over the contents, like so: for (map<int, int>::iterator x = someMap.begin(); x != someMap.end(); + +x) { int const& key = x->first; int& value = x->second; //do whatever with this (key, value) pair } Do you want to create a new container which holds all of the keys? Or holds all of the values? Then iterate over the contents and build the new container, like so: map<int, int> someMap; vector<int> listOfKeys; for (map<int, int>::iterator x = someMap.begin(); x != someMap.end(); + +x) listOfKeys.push_back(x->first); I would not write a separate function for a two liner using very basic standard library stuff like this. Wrapping such basic usage for ease of use does not result in ease of use. It results in only obfuscation. Joshua Maurice |
|
|
|
#7 |
|
Posts: n/a
|
On Nov 4, 1:05*pm, Alan Woodland <a...@aberystwyth.ac.uk> wrote:
> > There's a few annoying things about this though, the function take_first > has to live inside the anonymous namespace because it's not legal to > write the following, which given the absence of lambda functions would > be cleaner in my view: > > template <typename T1, typename T2> > std::list<T1> keys(const std::map<T1,T2>& in) { > * *struct { > * * *const T1& operator()(const typename std::map<T1,T2>::value_type& > pair) { > * * * *return pair.first; > * * *} > * *} take_first; > > * *std::list<T1> klist(in.size()); > * *std::transform(in.begin(), in.end(), klist.begin(), take_first); > * *return klist; > > } > This will work: template <typename T1, typename T2> std::list<T1> keys(const std::map<T1,T2>& in) { struct take_first{ static const T1& op(const typename std::map<T1,T2>::value_type& pair) { return pair.first; } }; std::list<T1> klist(in.size()); std::transform(in.begin(), in.end(), klist.begin(), &take_first: return klist; } HTH, -- gpd gpderetta |
|
![]() |
| Thread Tools | Search this Thread |
|
|
Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| Re: SP2(KB914961) installation fails 2003(64 bit) endpoint with 0x800705B3 | PA Bear [MS MVP] | Windows 64bit | 7 | 07-10-2009 05:38 PM |
| Values set by javascript are not reflected in serverside(.Net) | rchimakurty | Software | 2 | 11-28-2007 10:07 AM |
| Checkbox values problem in gridview | thanigaimani.thirumalai | Software | 0 | 11-09-2007 05:12 AM |
| How to make the form View save it's field values in Visual Stdio .NET | asammoud | Software | 0 | 07-17-2007 10:57 AM |
| Help with list of values | Abbigail | Computer Support | 1 | 09-23-2006 06:47 PM |