|
|
|
|
||||||
![]() |
|
|
LinkBack | Outils de la discussion |
|
|
#1 |
|
Messages: n/a
Hébergeur: |
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 |
|
|
|
#2 |
|
Messages: n/a
Hébergeur: |
<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. |
|
|
|
#3 |
|
Messages: n/a
Hébergeur: |
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); > } |
|
|
|
#4 |
|
Messages: n/a
Hébergeur: |
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. |
|
|
|
#5 |
|
Messages: n/a
Hébergeur: |
> 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. |
|
|
|
#6 |
|
Messages: n/a
Hébergeur: |
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 |
|
|
|
#7 |
|
Messages: n/a
Hébergeur: |
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. |
|
|
|
#8 |
|
Messages: n/a
Hébergeur: |
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 |
|
![]() |
| Outils de la discussion | |
|
|