
I'm just getting into boost and I really like it. I would like to iterate over keys of a multimap. so it would look like this: std::multimap<type, type>::key_iterator i = map.beginkey(); i != map.endkey(); i++ at each i++ it would move to the next key. -or- for_each(map.beginkey(), map.endkey(), whatever); Is this possible with the boost iterators? Thanks, Chris

Chris Goller <cgoller@magpiesystems.com> writes:
I'm just getting into boost and I really like it.
I would like to iterate over keys of a multimap.
so it would look like this:
std::multimap<type, type>::key_iterator i = map.beginkey(); i != map.endkey(); i++ at each i++ it would move to the next key.
-or-
for_each(map.beginkey(), map.endkey(), whatever);
Is this possible with the boost iterators?
You can't use that syntax, because there's no way to inject a key_iterator member into std::multimap. You could use a transform_iterator over the multimap's native iterator with select1st, defined as: struct select1st { template <class T, class U> T& operator()(std::pair<T,U>& p) const { return p.first } template <class T, class U> T const& operator()(std::pair<T,U> const& p) const { return p.first } }; HTH, -- Dave Abrahams Boost Consulting http://www.boost-consulting.com

David- Thanks. Upon reading my poorly phrased email I realized this: I want unique keys so that if the data looks like this: key value 3 1 1 2 1 4 4 3 5 5 5 9 So, what I would like to do is to a print each value for a particular key in such a way: key: value: 1---- |------2 |------4 3---- |------1 4---- |------3 5---- |------5 |------9 Or, for example, if I had a list of directories as keys and and files are their values then for each directory I could print out the file. Right now, I do this: for (multimap<string, string>::iterator dir = filesystem.begin(); i != filesystem.end()) { pair<multimap<string, string>::iterator, multimap<string, string>::iterator> bounds; bounds = filesystem.equal_range(dir->first); cout << dir->first << "----" << endl; for (multimap<string, string>::iterator file = bounds.first; file != bounds.second; file++) { cout << " |------" << file->second << endl; } // Moves the directory iterator to the next directory key. dir = file; } So, I'm trying to get better at using iterators much smarter. I would like to make this code much more concise. I figured that if I could jump from key to key I write the above code much cleaner. Thanks, Chris David Abrahams wrote:
Chris Goller <cgoller@magpiesystems.com> writes:
I'm just getting into boost and I really like it.
I would like to iterate over keys of a multimap.
so it would look like this:
std::multimap<type, type>::key_iterator i = map.beginkey(); i != map.endkey(); i++ at each i++ it would move to the next key.
-or-
for_each(map.beginkey(), map.endkey(), whatever);
Is this possible with the boost iterators?
You can't use that syntax, because there's no way to inject a key_iterator member into std::multimap. You could use a transform_iterator over the multimap's native iterator with select1st, defined as:
struct select1st { template <class T, class U> T& operator()(std::pair<T,U>& p) const { return p.first }
template <class T, class U> T const& operator()(std::pair<T,U> const& p) const { return p.first } };
HTH,

On Thu, 18 Nov 2004 15:21:06 -0700, Chris Goller <cgoller@magpiesystems.com> wrote:
David-
Thanks.
Upon reading my poorly phrased email I realized this:
I want unique keys so that if the data looks like this:
key value 3 1 1 2 1 4 4 3 5 5 5 9
So, what I would like to do is to a print each value for a particular key in such a way:
key: value: 1---- |------2 |------4 3---- |------1 4---- |------3 5---- |------5 |------9
Chris - the C++ standard says (about associative containers) "The fundamental property of iterators of associative containers is that they iterate through the containers in the nondescending order of keys where nondescending is defined by the comparison that was used to construct them." which says to me So, I guess you could construct a (forward-only) filtering&transforming iterator based on a multimap iterator that knew the last key it visited and skip any keys of equal ordering, using the maps ordering predicate (I'm assuming operator < here, which is wrong - use the multimap's predicate) : template<typename KeyType> bool KeysAreTheSame(KeyType k1, KeyType k2) { return !(k1<k2 || k2<k1); } It's a bit messy and would have to be forward-only and there's probably a better way of doing it...but I think it'd do what you want. Stuart Dootson

On Thu, 18 Nov 2004 15:21:06 -0700, Chris Goller <cgoller@magpiesystems.com> wrote:
David-
Thanks.
Upon reading my poorly phrased email I realized this:
I want unique keys so that if the data looks like this:
key value 3 1 1 2 1 4 4 3 5 5 5 9
So, what I would like to do is to a print each value for a particular key in such a way:
key: value: 1---- |------2 |------4 3---- |------1 4---- |------3 5---- |------5 |------9
Or, for example, if I had a list of directories as keys and and files are their values then for each directory I could print out the file. Right now, I do this:
for (multimap<string, string>::iterator dir = filesystem.begin(); i != filesystem.end()) { pair<multimap<string, string>::iterator, multimap<string, string>::iterator> bounds; bounds = filesystem.equal_range(dir->first); cout << dir->first << "----" << endl; for (multimap<string, string>::iterator file = bounds.first; file != bounds.second; file++) { cout << " |------" << file->second << endl; } // Moves the directory iterator to the next directory key. dir = file; }
So, I'm trying to get better at using iterators much smarter. I would like to make this code much more concise.
I figured that if I could jump from key to key I write the above code much cleaner.
You can use multimap::upper_bound instead of iter++ to help navigate the unique key space: using namespace std; using namespace boost::assign; typedef multimap<int, int> mymap; mymap m = map_list_of (1,1)(1,2)(1,3)(2,1)(2,2)(2,3)(3,1)(3,2)(4,9)(5,10); for (mymap::const_iterator i = m.begin (); i != m.end (); i = m.upper_bound (i->first)) cout << i->first << endl; outputs 1 2 3 4 5 -- Caleb Epstein caleb dot epstein at gmail dot com

I believe you could make your loop cleaner by using std::advance and std::count. Something like: multimap<string,string> MyMap; for (MyMap::iterator dir=filesystem.begin(); dir!=filesystem.end(); advance(dir,filesystem.count(*dir))) { } Chris Goller wrote:
David-
Thanks.
Upon reading my poorly phrased email I realized this:
I want unique keys so that if the data looks like this:
key value 3 1 1 2 1 4 4 3 5 5 5 9
So, what I would like to do is to a print each value for a particular key in such a way:
key: value: 1---- |------2 |------4 3---- |------1 4---- |------3 5---- |------5 |------9
Or, for example, if I had a list of directories as keys and and files are their values then for each directory I could print out the file. Right now, I do this:
for (multimap<string, string>::iterator dir = filesystem.begin(); i != filesystem.end()) { pair<multimap<string, string>::iterator, multimap<string, string>::iterator> bounds; bounds = filesystem.equal_range(dir->first); cout << dir->first << "----" << endl; for (multimap<string, string>::iterator file = bounds.first; file != bounds.second; file++) { cout << " |------" << file->second << endl; } // Moves the directory iterator to the next directory key. dir = file; }
So, I'm trying to get better at using iterators much smarter. I would like to make this code much more concise.
I figured that if I could jump from key to key I write the above code much cleaner.
Thanks,
Chris
David Abrahams wrote:
Chris Goller <cgoller@magpiesystems.com> writes:
I'm just getting into boost and I really like it.
I would like to iterate over keys of a multimap.
so it would look like this:
std::multimap<type, type>::key_iterator i = map.beginkey(); i != map.endkey(); i++ at each i++ it would move to the next key.
-or-
for_each(map.beginkey(), map.endkey(), whatever);
Is this possible with the boost iterators?
You can't use that syntax, because there's no way to inject a key_iterator member into std::multimap. You could use a transform_iterator over the multimap's native iterator with select1st, defined as:
struct select1st { template <class T, class U> T& operator()(std::pair<T,U>& p) const { return p.first }
template <class T, class U> T const& operator()(std::pair<T,U> const& p) const { return p.first } };
HTH,
participants (5)
-
Caleb Epstein
-
Chris Goller
-
David Abrahams
-
Jeffrey Holle
-
Stuart Dootson