Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Iterating over pair elements in a container of pairs (C++)

If I have a container (vector, list, etc) where each element is a std::pair, is there an easy way to iterate over each element of each pair?

i.e.

std::vector<std::pair<int,int> > a;
a.push_back(std::pair(1,3));
a.push_back(std::pair(2,3));
a.push_back(std::pair(4,2));
a.push_back(std::pair(5,2));
a.push_back(std::pair(1,5));

and then being able to iterate over the value: 1,3,2,3,4,2,5,2,1,5?

Similarly, what type of functor/function would return to me a container (of the same type) with a flat listing of the pair elements as above?

like image 348
Shamster Avatar asked Dec 03 '22 14:12

Shamster


2 Answers

For your first, you have to create your own iterator class, which pairs a flag indicating the within-pair position with a container<pair> iterator

For the second, it's easier, although to be as general as you want (container of same type) you need a template typedef. Here's for just vector:

template <class V>
std::vector<V> flatten_pairs(std::vector<std::pair<V,V> > const& a) {
  typedef std::vector<std::pair<V,V> > A;
  std::vector<V> ret;
  for (typename A::const_iterator i=a.begin(),e=a.end();i!=e;++i) {
    ret.push_back(i->first);
    ret.push_back(i->second);
  }
  return ret;
}

Here's how you fake a template typedef:

template <class C>
struct same_container;

template <class V>
struct same_container<std::vector<V> > {
  template <class W> struct rebind { typedef std::vector<W> type; };
};

template <class V>
struct same_list<std::list<V> > {
  template <class W> struct rebind { typedef std::list<W> type; };
};

template <class C>
typename same_container<C>::rebind<typename C::value_type::first_type>::type
flatten_pairs(C const& a);
like image 147
Jonathan Graehl Avatar answered Dec 11 '22 10:12

Jonathan Graehl


The following code will print all values as required:

for ( size_t x = 0; x < a.size(); ++x ) {
    cout << a[x].first << "," << a[x].second << ",";
}

I'd prefer this easy way than creating custom iterator.

like image 29
Kirill V. Lyadvinsky Avatar answered Dec 11 '22 11:12

Kirill V. Lyadvinsky