473,382 Members | 1,447 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,382 software developers and data experts.

Extracting keys and values in a map.

Ram
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

May 25 '06 #1
11 2705
Ram wrote:
[..]
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.
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").
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>

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
May 25 '06 #2
Ram
Victor Bazarov wrote:
Ram wrote:
[..]
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.


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").


I know I could always write my own adapter (and how). Thats not the
point here.
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>


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

May 25 '06 #3
Ram wrote:
Victor Bazarov wrote:
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>


I find your rant unjustified. [...]


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
May 25 '06 #4
Victor Bazarov wrote:
Ram wrote:
Victor Bazarov wrote:
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>


I find your rant unjustified. [...]


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 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.

May 25 '06 #5
Victor Bazarov wrote:
Ram wrote:
Victor Bazarov wrote:
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>

I find your rant unjustified. [...]


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:


<snip code example>
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.


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

May 25 '06 #6
Dilip wrote:
[..]
I second Ram.
On what grounds?
In addition to being the patrolman for this NG you are
unnecessarily being heavy handed on posters [..]
Patrolman? Heavy handed? Huh?
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.
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.
You need to cut us some slack every now & then.


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
May 25 '06 #7
Jonathan Mcdougall wrote:
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.


You know what, wrong time, buddy. I am not going to be insulted in
this way.
May 25 '06 #8
Victor Bazarov wrote:
Dilip wrote:
[..]
In addition to being the patrolman for this NG you are
unnecessarily being heavy handed on posters [..]
Patrolman? Heavy handed? Huh?


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.
If you
(or Ram) don't want to spend time reading those same books or doing
research elsewhere,


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.
You need to cut us some slack every now & then.


And do *I* get any slack at all? Pff... Forget it! Not worth my time.


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?

May 25 '06 #9
Victor Bazarov wrote:
Jonathan Mcdougall wrote:
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.


You know what, wrong time, buddy. I am not going to be insulted in
this way.


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

May 25 '06 #10
Dilip wrote:
[..] What does ranting publicly buy you other than maybe
making you feel good for that few minutes?


Look in the mirror, pal.
May 25 '06 #11
Ram
[...]

I find your rant unjustified. [...]
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 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.
I suggested (against my better judgement, apparently) to look at Boost.
But if you find Boost syntax unsatisfactory, well, how can we help?
By suggesting some simple way to provide my own.
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> [...] -------------------
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()); }
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.


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

May 26 '06 #12

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: svilen | last post by:
hi. this was named but it is misleading. i want to have the order of setting items in intrinsic dicts (keyword args, or class attributes, etc). which is, a prdered dict trhat matches the...
10
by: shark | last post by:
row = {"fname" : "Frank", "lname" : "Jones", "city" : "Hoboken", "state" : "Alaska"} cols = ("city", "state") Is there a best-practices way to ask for an object containing only the keys named...
0
by: mtp1032 | last post by:
I need to be able to extract the values from an XmlRpcValue where I do not know in advance what the keys are, or how many exist. For example, suppose I have an XmlRpcValue, xmlVal, returned by some...
2
by: mtp1032 | last post by:
I need to be able to extract the values from an XmlRpcValue where I do not know in advance what the keys are, or how many exist. For example, suppose I have an XmlRpcValue, object, returned by...
16
by: Preben Randhol | last post by:
Hi A short newbie question. I would like to extract some values from a given text file directly into python variables. Can this be done simply by either standard library or other libraries? Some...
14
by: vatamane | last post by:
This has been bothering me for a while. Just want to find out if it just me or perhaps others have thought of this too: Why shouldn't the keyset of a dictionary be represented as a set instead of a...
6
by: geegeegeegee | last post by:
Hi All, I have come across a difficult problem to do with extracting UniCode characters from RTF strings. A detailed description of my problem is below, if anyone could help, it would be much...
13
by: Nader | last post by:
Hello, I have a dictionary and will get all keys which have the same values. d = {('a' : 1), ('b' : 3), ('c' : 2),('d' : 3),('e' : 1),('f' : 4)} I will something as : d.keys(where their...
2
by: lunabelle22a | last post by:
Hi, I have 125 unique variables and corresponding values in a data file with 6 fixed-width columns (columns alternate between "variables" and "values"). If I only need 6 of these variables and...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.