Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > To retrieve Keys or values of a Map

Reply
Thread Tools

To retrieve Keys or values of a Map

 
 
Saeed Amrollahi
Guest
Posts: n/a
 
      11-04-2009
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.
 
Reply With Quote
 
 
 
 
Alan Woodland
Guest
Posts: n/a
 
      11-04-2009
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:stream_iterator<std::string>(std::cout, "\n"));

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
 
Reply With Quote
 
 
 
 
Saeed Amrollahi
Guest
Posts: n/a
 
      11-05-2009
On Nov 4, 3:05*pm, Alan Woodland <(E-Mail Removed)> 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:stream_iterator<std::string>(std::cout, "\n"));
>
> * *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
 
Reply With Quote
 
mzdude
Guest
Posts: n/a
 
      11-05-2009
On Nov 4, 4:44*am, Saeed Amrollahi <(E-Mail Removed)> 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:air<std::wstring,std::wstring> MapPairType;

MyMapType MyMap;

template<typename U>
std::list<typename U::key_type> getKeys(U const &m)
{
typedef std:air<typename U::key_type,typename U::mapped_type>
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;
}
 
Reply With Quote
 
Saeed Amrollahi
Guest
Posts: n/a
 
      11-06-2009
On Nov 5, 5:30*pm, mzdude <(E-Mail Removed)> wrote:
> On Nov 4, 4:44*am, Saeed Amrollahi <(E-Mail Removed)> 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:air<std::wstring,std::wstring> MapPairType;
>
> MyMapType MyMap;
>
> template<typename U>
> std::list<typename U::key_type> getKeys(U const &m)
> {
> * *typedef std:air<typename U::key_type,typename U::mapped_type>
> 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.
 
Reply With Quote
 
Joshua Maurice
Guest
Posts: n/a
 
      11-06-2009
On Nov 4, 1:44*am, Saeed Amrollahi <(E-Mail Removed)> 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.
 
Reply With Quote
 
gpderetta
Guest
Posts: n/a
 
      11-12-2009
On Nov 4, 1:05*pm, Alan Woodland <(E-Mail Removed)> 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:p);
return klist;
}

HTH,

--
gpd
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Changing map keys (no reordering of keys) alan C++ 3 11-28-2007 03:17 PM
Extracting keys and values in a map. Ram C++ 11 05-26-2006 04:03 AM
Best wa to retrieve keys of a map Marco Spatz C++ 3 05-08-2006 09:21 PM
searching keys in std::map using map::upper_bound Erik Arner C++ 0 11-02-2004 11:14 PM
Map Iterator is wrapped for keys and values - compiler error sks_cpp C++ 0 07-26-2003 01:20 AM



Advertisments