PHWinfo banniere

Titres
PORTAIL ANNUAIRE ARTICLES COMPARATEUR HÉBERGEURS DEVIS FORUMS RÉDUCTEUR D'URL
Précédent   PHWinfo > Autres forums > Forum Programmation & Conception > comp.lang.cplus > Initialize a std::set with keys from a std::map
S'inscrire FAQ Membres Recherche Messages du jour Marquer les forums comme lus
Initialize a std::set with keys from a std::map

Réponse
 
LinkBack Outils de la discussion
Vieux 16/01/2008, 01h00   #1
brzrkr0@gmail.com
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Initialize a std::set with keys from a std::map

A portion of my program needs to initialize a std::set<int> to have
all the keys in a std::map<int, double>. The code I've pasted below
works, but I'm wondering if there's a more elegant way to do it (an
STL algorithm, maybe?). I'm a bit of an STL noob, so any advice
people can give would be greatly appreciated.


typedef std::map<int, double> intDoubleMap;
typedef std::set<int> intSet;

intSet v;
// map is an intDoubleMap* and has been initialized with some values
for (intDoubleMap::const_iterator it = map->begin();
it != map->end();
it++) {
int i = it->first;
v.insert(i);
}


Thanks,
Casey
  Réponse avec citation
Vieux 16/01/2008, 02h42   #2
Andrew Koenig
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Initialize a std::set with keys from a std::map

<brzrkr0@gmail.com> wrote in message
news:2d8e0a59-0448-44d1-95dc-eba7c4c7310b@m34g2000hsf.googlegroups.com...

> typedef std::map<int, double> intDoubleMap;
> typedef std::set<int> intSet;
>
> intSet v;
> // map is an intDoubleMap* and has been initialized with some values
> for (intDoubleMap::const_iterator it = map->begin();
> it != map->end();
> it++) {
> int i = it->first;
> v.insert(i);
> }


Looks reasonable to me. If I were being picky, I'd change it++ to ++it
(because there is no reason to copy the iterator and then throw the original
value away) and I'd collapse

int i = it-> first;
v.insert(i);

into

v.insert(it->first);

but aside from that, I can't think offhand of a way of doing it that
wouldn't be much harder to understand (and without any obvious compensating
gain).

I might be missing something -- it wouldn't be the first time -- but there
is virtue in being straightforward.


  Réponse avec citation
Vieux 16/01/2008, 04h07   #3
Daniel T.
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Initialize a std::set with keys from a std::map

brzrkr0@gmail.com wrote:

> A portion of my program needs to initialize a std::set<int> to have
> all the keys in a std::map<int, double>. The code I've pasted below
> works, but I'm wondering if there's a more elegant way to do it (an
> STL algorithm, maybe?). I'm a bit of an STL noob, so any advice
> people can give would be greatly appreciated.



transform( map->begin(), map->end(), inserter( v, v.begin() ),
select1st<intDoubleMap::value_type>() );


Note, "select1st" is part of the STL, but not part of the standard
library. It's easy to implement though and is generally useful:

template <typename Pair>
struct select1st : unary_function<Pair, typename Pair::first_type>
{
const typename Pair::first_type& operator()(const Pair& x) const {
return x.first;
}
};


Or you can use the boost lambda library:

transform( map->begin(), map->end(), inserter( v, v.begin() ),
bind(&intDoubleMap::value_type::first, _1 ) );



> typedef std::map<int, double> intDoubleMap;
> typedef std::set<int> intSet;
>
> intSet v;
> // map is an intDoubleMap* and has been initialized with some values
> for (intDoubleMap::const_iterator it = map->begin();
> it != map->end();
> it++) {
> int i = it->first;
> v.insert(i);
> }

  Réponse avec citation
Vieux 16/01/2008, 04h41   #4
Jerry Coffin
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Initialize a std::set with keys from a std::map

In article <2d8e0a59-0448-44d1-95dc-
eba7c4c7310b@m34g2000hsf.googlegroups.com>, brzrkr0@gmail.com says...
> A portion of my program needs to initialize a std::set<int> to have
> all the keys in a std::map<int, double>.


Why? Is there a reason you can't just leave the data in the map, and
temporarily ignore the associated data?

> The code I've pasted below
> works, but I'm wondering if there's a more elegant way to do it (an
> STL algorithm, maybe?). I'm a bit of an STL noob, so any advice
> people can give would be greatly appreciated.


Andrew Koenig has already pointed out a couple of minor changes. In
theory, I think you could probably create a special iterator type that
returns whatever.first when you dereference it, but (quite frankly) I
think that's more trouble than it's worth unless you're doing things
like this in quite a few different places. If memory serves, boost has
some iterators that can do that sort of thing for a boot tuple, and
similar (maybe even identical) code would probably work for std::pair as
well (though I haven't looked at it, so I'm not sure -- for that matter,
my memory may just be bad, and no such thing exists at all...)

--
Later,
Jerry.

The universe is a figment of its own imagination.
  Réponse avec citation
Vieux 16/01/2008, 06h58   #5
LBCninja@gmail.com
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Initialize a std::set with keys from a std::map

> Why? Is there a reason you can't just leave the data in the map, and
> temporarily ignore the associated data?


I was just thinking about that. I know the set is used in a
std::set_union algorithm downstream, so I'll have to figure if that
algorithm works with maps (and hash_maps) tomorrow. I checked the
set_union docs on sgi.com, but it's cryptic enough that I can't really
tell.

Daniel, your suggestion looks neat. If I can't avoid making the set
altogether I'll give that a try.
  Réponse avec citation
Vieux 16/01/2008, 10h46   #6
James Kanze
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Initialize a std::set with keys from a std::map

On Jan 16, 7:58 am, LBCni...@gmail.com wrote:
> > Why? Is there a reason you can't just leave the data in the map, and
> > temporarily ignore the associated data?


> I was just thinking about that. I know the set is used in a
> std::set_union algorithm downstream, so I'll have to figure if
> that algorithm works with maps (and hash_maps) tomorrow.


First, it won't work at all with a hash_map, because it requires
its input to be ordered, and hash_map isn't. And it won't work
with a map unless you provide a special comparison function,
because by default, comparison of the pair will involve both
elements. On the other hand, Jerry's suggestion involving the
special iterator sounds like just the ticket here: you pass the
special iterator to set_union, and it only sees the keys.

> I checked the set_union docs on sgi.com, but it's cryptic
> enough that I can't really tell.


I checked in the standard, and it isn't really clear either. I
think some of the requirements are missing: what happens if the
two input iterators have different value_type, for example?

--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
  Réponse avec citation
Vieux 16/01/2008, 13h53   #7
Daniel T.
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Initialize a std::set with keys from a std::map

LBCninja@gmail.com wrote:

> > Why? Is there a reason you can't just leave the data in the map, and
> > temporarily ignore the associated data?

>
> I was just thinking about that. I know the set is used in a
> std::set_union algorithm downstream, so I'll have to figure if that
> algorithm works with maps (and hash_maps) tomorrow. I checked the
> set_union docs on sgi.com, but it's cryptic enough that I can't really
> tell.


Well, for set_union, the SGI docs say:

InputIterator1 and InputIterator2 [must] have the same value type.

So it depends on what the other input iterator is. If it's two maps then
you are OK with using set_union on them.
  Réponse avec citation
Vieux 16/01/2008, 20h12   #8
James Kanze
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Initialize a std::set with keys from a std::map

On Jan 16, 2:53 pm, "Daniel T." <danie...@earthlink.net> wrote:
> LBCni...@gmail.com wrote:
> > > Why? Is there a reason you can't just leave the data in the map, and
> > > temporarily ignore the associated data?


> > I was just thinking about that. I know the set is used in a
> > std::set_union algorithm downstream, so I'll have to figure if that
> > algorithm works with maps (and hash_maps) tomorrow. I checked the
> > set_union docs on sgi.com, but it's cryptic enough that I can't really
> > tell.


> Well, for set_union, the SGI docs say:


> InputIterator1 and InputIterator2 [must] have the same value type.


That makes sense, of course---I don't see how the algorithm
could work otherwise. But I can't find this requirement in the
standard.

> So it depends on what the other input iterator is. If it's two
> maps then you are OK with using set_union on them.


Really? I think you mean if it's two instantiations of the same
map type. I've sure that using a map< string, int > for the
first, and a map< int, string > for the second won't work. And
even if the two containers are the same map type, unless you
provide a custom comparison function, you're likely to end up
with duplicate entries: the default comparison for the
value_type of the map iterators takes both the key and the
mapped value into consideration.

--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
  Réponse avec citation
Réponse


Outils de la discussion

Règles de messages
Vous ne pouvez pas créer de nouvelles discussions
Vous ne pouvez pas envoyer des réponses
Vous ne pouvez pas envoyer des pièces jointes
Vous ne pouvez pas modifier vos messages

Les balises BB sont activées : oui
Les smileys sont activés : oui
La balise [IMG] est activée : oui
Le code HTML peut être employé : non
Trackbacks are oui
Pingbacks are oui
Refbacks are oui


Fuseau horaire GMT +1. Il est actuellement 18h27.


Édité par : vBulletin® version 3.7.2
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.2.0 RC5 Tous droits réservés.
Version française #16 par l'association vBulletin francophone
PHWinfo est un site Éducation Sans Frontières
Ad Management by RedTyger
©Tous droits réservés par les parties respectives
Page generated in 0,15543 seconds with 16 queries