Extracting keys and values in a map. | | |
Hi,
I would like a sequence view of keys and values in a map, i.e. to
extract keys/values instead of using a loop
std::map<T1, T2> m;
std::list<T2> l;
// ...
std::map<T1, T2>::iterator it;
for(it = m.begin(); it != m.end(); ++it)
l.push_back(it->second);
I want to say something like
std::map<T1, T2> m;
std::list<T2> l;
// ...
std::copy(m.value_begin(), m.value_end(), std::inserter(l, l.end()));
In short my question reduces to- is there a simple way to get an
appropriate type of iterator from a map which on de-referencing gives
me key/value of the map.
I know its not difficult to roll out my own, just wondering whether
there's already a way to do it.
Thanks
Ram | | | | re: Extracting keys and values in a map.
Ram wrote:[color=blue]
> [..]
> In short my question reduces to- is there a simple way to get an
> appropriate type of iterator from a map which on de-referencing gives
> me key/value of the map.[/color]
WTF is "key/value"? Dereferencing a map iterator gives you a pair
(which is what 'value_type' of the map is). You can always write your
adapter to get the "second" member of it (or the "first").
[color=blue]
> I know its not difficult to roll out my own, just wondering whether
> there's already a way to do it.[/color]
To do what? Extract "second"? Boost has an adapter for it, IIRC,
but if you're not currently using Boost, rolling your own is simpler
than waiting for it to tricle into the library implemenations.
<rant>
Programming always involves writing a bunch of small utility code that
serves some special needs. Why everybody keeps asking if all those
special needs have already been addressed in the library is beyond me,
aren't there books from which you can learn what is and what isn't in
the standard library? Do your homework before coming here. Try not
to use this newsgroup like a live reference manual for C++...
</rant>
V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask | | | | re: Extracting keys and values in a map.
Victor Bazarov wrote:[color=blue]
> Ram wrote:[color=green]
> > [..]
> > In short my question reduces to- is there a simple way to get an
> > appropriate type of iterator from a map which on de-referencing gives
> > me key/value of the map.[/color]
>
> WTF is "key/value"? Dereferencing a map iterator gives you a pair
> (which is what 'value_type' of the map is). You can always write your
> adapter to get the "second" member of it (or the "first").
>[/color]
I know I could always write my own adapter (and how). Thats not the
point here.
[color=blue][color=green]
> > I know its not difficult to roll out my own, just wondering whether
> > there's already a way to do it.[/color]
>
> To do what? Extract "second"? Boost has an adapter for it, IIRC,
> but if you're not currently using Boost, rolling your own is simpler
> than waiting for it to tricle into the library implemenations.
>
> <rant>
> Programming always involves writing a bunch of small utility code that
> serves some special needs. Why everybody keeps asking if all those
> special needs have already been addressed in the library is beyond me,
> aren't there books from which you can learn what is and what isn't in
> the standard library? Do your homework before coming here. Try not
> to use this newsgroup like a live reference manual for C++...
> </rant>
>[/color]
I find your rant unjustified. IMO this is not a very special need.
While using std::map many times I have found the need to extract just
keys (or values) in the map. And most of the time I have rolled my own
loops.
I ain't trying to use this newsgroup as a live reference manual. Have a
couple of them and its easier to use them than posting here. I found a
way using boost::lambda and boost::bind but the syntax didn't satisfy
me. My purpose of posting this here was to get some idea of how to do
it in a concise and elegant manner. If this newsgroup is not for this I
wonder what it is for.
Ram | | | | re: Extracting keys and values in a map.
Ram wrote:[color=blue]
> Victor Bazarov wrote:[color=green]
>> Ram wrote:[color=darkred]
>>> [..]
>>> I know its not difficult to roll out my own, just wondering whether
>>> there's already a way to do it.[/color]
>>
>> To do what? Extract "second"? Boost has an adapter for it, IIRC,
>> but if you're not currently using Boost, rolling your own is simpler
>> than waiting for it to tricle into the library implemenations.
>>
>> <rant>
>> Programming always involves writing a bunch of small utility code
>> that serves some special needs. Why everybody keeps asking if all
>> those special needs have already been addressed in the library is
>> beyond me, aren't there books from which you can learn what is and
>> what isn't in the standard library? Do your homework before coming
>> here. Try not to use this newsgroup like a live reference manual
>> for C++... </rant>
>>[/color]
>
> I find your rant unjustified. [...][/color]
I am sorry. Unjustified?! You asked (see above) whether there's already
a way to do it. "Already". What does that mean to you? "There": where?
We can only tell you about the language and about the library. That's
the only "there" where anything can be, AFA c.l.c++ is concerned.
I suggested (against my better judgement, apparently) to look at Boost.
But if you find Boost syntax unsatisfactory, well, how can we help?
If you know how to roll your own, isn't that "a way to do it" that is
"already" "there"? How much more elegant do you need to get beyond
a simple 'for' loop? I told you about the adapter that you can write.
Do you expect me to write it for you, or are you a programmer yourself?
OK, here you go:
-------------------
#include <map>
#include <iterator>
template<class mi, class t> struct key_iterator_tag
{
typedef std::input_iterator_tag iterator_category;
typedef t value_type;
typedef ptrdiff_t difference_type;
typedef difference_type distance_type; // retained
typedef t* pointer;
typedef t& reference;
mi iter;
key_iterator_tag(mi it) : iter(it) {}
bool operator !=(key_iterator_tag const& other) const {
return iter != other.iter;
}
bool operator ==(key_iterator_tag const& other) const {
return iter == other.iter;
}
key_iterator_tag& operator++() { ++iter; return *this; }
key_iterator_tag operator++(int) {
key_iterator_tag i(*this); ++iter; return i; }
t operator*() const { return (*iter).first; }
};
template<class mi, class t> struct mapped_iterator_tag
{
typedef std::input_iterator_tag iterator_category;
typedef t value_type;
typedef ptrdiff_t difference_type;
typedef difference_type distance_type; // retained
typedef t* pointer;
typedef t& reference;
mi iter;
mapped_iterator_tag(mi it) : iter(it) {}
bool operator !=(mapped_iterator_tag const& other) const {
return iter != other.iter;
}
bool operator ==(mapped_iterator_tag const& other) const {
return iter == other.iter;
}
mapped_iterator_tag& operator++() { ++iter; return *this; }
mapped_iterator_tag operator++(int) {
mapped_iterator_tag i(*this); ++iter; return i; }
t& operator*() { return (*iter).second; }
};
template<class mi>
key_iterator_tag<typename mi::iterator, typename mi::key_type>
key_begin(mi& m) {
return key_iterator_tag<typename mi::iterator, typename
mi::key_type>(m.begin());
}
template<class mi>
key_iterator_tag<typename mi::iterator, typename mi::key_type>
key_end(mi& m) {
return key_iterator_tag<typename mi::iterator, typename
mi::key_type>(m.end());
}
template<class mi>
mapped_iterator_tag<typename mi::iterator, typename mi::mapped_type>
mapped_begin(mi& m) {
return mapped_iterator_tag<typename mi::iterator, typename
mi::mapped_type>(m.begin());
}
template<class mi>
mapped_iterator_tag<typename mi::iterator, typename mi::mapped_type>
mapped_end(mi& m) {
return mapped_iterator_tag<typename mi::iterator, typename
mi::mapped_type>(m.end());
}
#include <iostream>
#include <list>
#include <algorithm>
int main(int argc, char** argv)
{
std::map<int,char> mic;
mic[1] = 'a';
mic[3] = 'b';
mic[2] = 'c';
std::list<int> li;
std::list<char> lc;
std::copy(key_begin(mic), key_end(mic), back_inserter(li));
for (std::list<int>::iterator i = li.begin(); i != li.end(); ++i)
std::cout << *i << std::endl;
std::copy(mapped_begin(mic), mapped_end(mic), back_inserter(lc));
for (std::list<char>::iterator i = lc.begin(); i != lc.end(); ++i)
std::cout << *i << std::endl;
}
-------------------
Now, the use of those is 'key_begin(somemap)' and 'key_end(somemap)' and
they are input iterators. Is that elegant enough? Probably not. You work
on improving the elegance, I'm done.
V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask | | | | re: Extracting keys and values in a map.
Victor Bazarov wrote:[color=blue]
> Ram wrote:[color=green]
> > Victor Bazarov wrote:[color=darkred]
> >> Ram wrote:
> >>> [..]
> >>> I know its not difficult to roll out my own, just wondering whether
> >>> there's already a way to do it.
> >>
> >> To do what? Extract "second"? Boost has an adapter for it, IIRC,
> >> but if you're not currently using Boost, rolling your own is simpler
> >> than waiting for it to tricle into the library implemenations.
> >>
> >> <rant>
> >> Programming always involves writing a bunch of small utility code
> >> that serves some special needs. Why everybody keeps asking if all
> >> those special needs have already been addressed in the library is
> >> beyond me, aren't there books from which you can learn what is and
> >> what isn't in the standard library? Do your homework before coming
> >> here. Try not to use this newsgroup like a live reference manual
> >> for C++... </rant>
> >>[/color]
> >
> > I find your rant unjustified. [...][/color]
>
> I am sorry. Unjustified?! You asked (see above) whether there's already
> a way to do it. "Already". What does that mean to you? "There": where?
> We can only tell you about the language and about the library. That's
> the only "there" where anything can be, AFA c.l.c++ is concerned.[/color]
I second Ram. In addition to being the patrolman for this NG you are
unnecessarily being heavy handed on posters who are genuinely trying to
find a *better* solution to a problem they face. Not everyone can
quote the standard like you do nor do they have the breadth of
expertise you do. Admittedly you have spent time & energy getting
there, but lesser mortals like us are not there yet.
You have wasted 2 lengthy posts on semantic clinton-esque mumbo-jumbo
(it depends on what you mean by "what") when it would have been far
more easier to either ignore that post altogether or else post a quick
snippet (as long as the topic is not OT). I am sure for someone like
you it'd be childs play. Whether you want to spend time doing that is
a separate issue -- I do not however think you have a right to question
the OP's motives.
I posted a similar question in another thread. Its not that I don't
want to do some thinking myself (In fact I have). Its just that my
knowledge and my capacity is limited to what I know. The motivation
behind my post sometimes is a reply can teach you a lot -- like the one
where you showed me how to use a << operator to wrap a legacy logging
library. It maybe simple for you but it opened some possibilities for
me.
You need to cut us some slack every now & then. | | | | re: Extracting keys and values in a map.
Victor Bazarov wrote:[color=blue]
> Ram wrote:[color=green]
> > Victor Bazarov wrote:[color=darkred]
> >> Ram wrote:
> >>> [..]
> >>> I know its not difficult to roll out my own, just wondering whether
> >>> there's already a way to do it.
> >>
> >> To do what? Extract "second"? Boost has an adapter for it, IIRC,
> >> but if you're not currently using Boost, rolling your own is simpler
> >> than waiting for it to tricle into the library implemenations.
> >>
> >> <rant>
> >> Programming always involves writing a bunch of small utility code
> >> that serves some special needs. Why everybody keeps asking if all
> >> those special needs have already been addressed in the library is
> >> beyond me, aren't there books from which you can learn what is and
> >> what isn't in the standard library? Do your homework before coming
> >> here. Try not to use this newsgroup like a live reference manual
> >> for C++... </rant>
> >>[/color]
> >
> > I find your rant unjustified. [...][/color]
>
> I am sorry. Unjustified?! You asked (see above) whether there's already
> a way to do it. "Already". What does that mean to you? "There": where?
> We can only tell you about the language and about the library. That's
> the only "there" where anything can be, AFA c.l.c++ is concerned.
>
> I suggested (against my better judgement, apparently) to look at Boost.
> But if you find Boost syntax unsatisfactory, well, how can we help?
>
> If you know how to roll your own, isn't that "a way to do it" that is
> "already" "there"? How much more elegant do you need to get beyond
> a simple 'for' loop? I told you about the adapter that you can write.
> Do you expect me to write it for you, or are you a programmer yourself?
>
> OK, here you go:[/color]
<snip code example>
[color=blue]
> Now, the use of those is 'key_begin(somemap)' and 'key_end(somemap)' and
> they are input iterators. Is that elegant enough? Probably not. You work
> on improving the elegance, I'm done.[/color]
Victor,
This tone is unacceptable here. Although your contribution to
comp.lang.c++ is extremely valuable, please do make an effort to keep
conversations pleasant for everybody, readers and posters.
Jonathan | | | | re: Extracting keys and values in a map.
Dilip wrote:[color=blue]
> [..]
> I second Ram.[/color]
On what grounds?
[color=blue]
> In addition to being the patrolman for this NG you are
> unnecessarily being heavy handed on posters [..][/color]
Patrolman? Heavy handed? Huh?
[color=blue]
> I posted a similar question in another thread. Its not that I don't
> want to do some thinking myself (In fact I have). Its just that my
> knowledge and my capacity is limited to what I know. The motivation
> behind my post sometimes is a reply can teach you a lot -- like the
> one where you showed me how to use a << operator to wrap a legacy
> logging library. It maybe simple for you but it opened some
> possibilities for me.[/color]
But it is all described in a few books I've managed to read during off
hours, or between coding, when the projects are being built. If you
(or Ram) don't want to spend time reading those same books or doing
research elsewhere, I'm gonna rant about it. And nothing you can do
'bout that. I ain't gonna change. Live with it.
[color=blue]
> You need to cut us some slack every now & then.[/color]
And do *I* get any slack at all? Pff... Forget it! Not worth my time.
V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask | | | | re: Extracting keys and values in a map.
Jonathan Mcdougall wrote:[color=blue]
> Victor,
>
> This tone is unacceptable here. Although your contribution to
> comp.lang.c++ is extremely valuable, please do make an effort to keep
> conversations pleasant for everybody, readers and posters.[/color]
You know what, wrong time, buddy. I am not going to be insulted in
this way. | | | | re: Extracting keys and values in a map.
Victor Bazarov wrote:[color=blue]
> Dilip wrote:[color=green]
> > [..]
> > In addition to being the patrolman for this NG you are
> > unnecessarily being heavy handed on posters [..][/color]
>
> Patrolman? Heavy handed? Huh?[/color]
This snip is a shining example:
"I'm gonna rant about it. And nothing you can do
'bout that. I ain't gonna change. Live with it."
If that is not heavy handed I don't know what is.
[color=blue]
> If you
> (or Ram) don't want to spend time reading those same books or doing
> research elsewhere,[/color]
That is where you start the assumption phase. Maybe we did the
research, maybe we read the same books, maybe we just didn't know where
to look or maybe we looked and we still didn't get it. Maybe we kept
running into deadlines thats not allowing us enough time to investigate
all possibilities. Thats what I meant by "capacity". Some people get
that epiphany faster than others. Humility means sharing what you know
and not reflexively questioning every one's motivation. No one is
downplaying your contribution to this NG -- we only ask you to simmer
down a little bit.
[color=blue][color=green]
> > You need to cut us some slack every now & then.[/color]
>
> And do *I* get any slack at all? Pff... Forget it! Not worth my time.[/color]
Thats exactly what I mean. When something is not worth your time, just
ignore it. What does ranting publicly buy you other than maybe making
you feel good for that few minutes? | | | | re: Extracting keys and values in a map.
Victor Bazarov wrote:[color=blue]
> Jonathan Mcdougall wrote:[color=green]
> > Victor,
> >
> > This tone is unacceptable here. Although your contribution to
> > comp.lang.c++ is extremely valuable, please do make an effort to keep
> > conversations pleasant for everybody, readers and posters.[/color]
>
> You know what, wrong time, buddy. I am not going to be insulted in
> this way.[/color]
I don't know you, why would I insult you? I am sorry to see you taking
things this way. Anyways, this thread is closed for me.
Jonathan | | | | re: Extracting keys and values in a map.
Dilip wrote:[color=blue]
> [..] What does ranting publicly buy you other than maybe
> making you feel good for that few minutes?[/color]
Look in the mirror, pal. | | | | re: Extracting keys and values in a map.
[...][color=blue][color=green]
> >
> > I find your rant unjustified. [...][/color]
>
> I am sorry. Unjustified?! You asked (see above) whether there's already
> a way to do it. "Already". What does that mean to you? "There": where?
> We can only tell you about the language and about the library. That's
> the only "there" where anything can be, AFA c.l.c++ is concerned.[/color]
I think it was clear that I was not asking for a pointer to the
standard library. You could have pointed me to the boost adapter you
talked about and that would have done. IMO language is not only about
the syntax and the library but also about the way it facilitates one to
solve a problem.
[color=blue]
> I suggested (against my better judgement, apparently) to look at Boost.
> But if you find Boost syntax unsatisfactory, well, how can we help?[/color]
By suggesting some simple way to provide my own.
[color=blue]
> If you know how to roll your own, isn't that "a way to do it" that is
> "already" "there"? How much more elegant do you need to get beyond
> a simple 'for' loop? I told you about the adapter that you can write.
> Do you expect me to write it for you, or are you a programmer yourself?
>
> OK, here you go:
> -------------------
> #include <map>[/color]
[...][color=blue]
> -------------------[/color]
I didn't expect you to write it for me, rather to provide some ideas in
that direction. For example, one suggestion would be to derive from
std::map<T1, T2>::iterator that overrides operators * and -> to return
appropriate type as I have done below for keys-
template <class T1, class T2>
struct key_iterator: public std::map<T1, T2>::iterator
{
typedef typename std::map<T1, T2>::iterator base_t;
typedef const T1* pointer; // override
typedef const T1& reference; // override
reference operator*() const
{ return base_t::operator*().first; }
pointer operator->() const
{ return &(base_t::operator*().first); }
key_iterator() {}
key_iterator(base_t b): base_t(b) {}
};
template <class T1, class T2>
key_iterator<T1, T2> key_begin(std::map<T1, T2> &m)
{ return key_iterator<T1, T2>(m.begin()); }
template <class T1, class T2>
key_iterator<T1, T2> key_end(std::map<T1, T2> &m)
{ return key_iterator<T1, T2>(m.end()); }
[color=blue]
> Now, the use of those is 'key_begin(somemap)' and 'key_end(somemap)' and
> they are input iterators. Is that elegant enough? Probably not. You work
> on improving the elegance, I'm done.[/color]
I don't want to compare my solution with yours. But one problem can be
approached in different ways by different people and thats what I was
looking for.
Thank you for your time. I didn't wish this post to go where it went.
Its time to close it now.:)
Ram |  | | | | /bytes/about
We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights.
Get the best answers to your questions from over 226,419 network members.
|