Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Iterator for second to last element in a list

I currently have the following for loop:

for(list<string>::iterator jt=it->begin(); jt!=it->end()-1; jt++)

I have a list of strings which is in a larger list (list<list<string> >). I want to loop through the contents of the innerlist until I get to the 2nd to last element. This is because I have already processed the contents of the final element, and have no reason to process them again.

However, using it->end()-1 is invalid -- I cannot use the - operator here. While I could use the -- operator, this would decrement this final iterator on each cycle.

I believe a STL list is a doubly linked list, so from my perspective, it should be possible to do this.

Advice? Thanks in advance

like image 817
BSchlinker Avatar asked Jun 21 '11 19:06

BSchlinker


People also ask

How do I get the iterator to the last element in a list?

The list::end() is a built-in function in C++ STL which is used to get an iterator to past the last element. By past the last element it is meant that the iterator returned by the end() function return an iterator to an element which follows the last element in the list container.

How do you get the second last element of a set?

If you have a set, just decrement the end iterator twice. Or: auto it = std::prev(some_set. end(), 2); .

What is iterator second?

Refers to the first ( const ) element of the pair object pointed to by the iterator - i.e. it refers to a key in the map. Instead, the expression: i->second.


2 Answers

Requisite recommendation to use the standard library:

std::for_each(lst.begin(), --lst.end(), process);

If you don't want to hassle with creating a functor [I almost never do], and you can't use reverse iterators, hoist the end check out of the loop:

for(iterator i = lst.begin(), j = --lst.end(); i != j; ++i) {
    // do
    // stuff
}

Or, you can just trust the optimizer to recognize that it doesn't have to keep recreating the end condition, and do the hoisting itself. How reliable this is depends on the list implementation, and how complex your loop code is, and how good your optimizer is.

At any rate, just do what is easiest for you to understand, and worry about performance after you're done.

like image 164
Dennis Zickefoose Avatar answered Oct 24 '22 05:10

Dennis Zickefoose


List iterator is not random iterator. You should do the following:

if ( ! it->empty() )
{
  list<string>::iterator test = it->end();
  --test;
  for( list<string>::iterator jt = it->begin(); jt != test; ++jt )
  {
  ...
  }
}

One more thing: use ++jt against jt++. jt++ source code usually looks something like this:

iterator operator++ (int i)
{
  iterator temp = (*this);
  ++(*this);
  return temp;
}; 
like image 44
Naszta Avatar answered Oct 24 '22 03:10

Naszta