hazer
hazer

Reputation: 47

Iterator two dimensional list

I am trying to scroll a two dimensional list with an iterator and I know that I'm missing something but I don't know what.

So the idea is that I'll have some commands to parse.

schema of my list

I put them on a list then I want to check if a member of the list is equal to "data.txt" for example. So I did an iterator for this, but as it is a two dimensional list with an std::pair inside it, I don't know how to implement this iterator. I did this but it isn't good, I can't read both list.

typedef std::list<std::string>  listStr;

std::list <std::pair<listStr, int> >  _execCmd;


int     Parser::execCmd()
{
   std::list<std::string>::const_iterator i;

   for (i = _execCmd.front().first.begin(); i != _execCmd.back().first.end(); ++i)                                          
    {                                                         
      if (*i == "Search.txt")                                       
        execSearch();                                          
      else if (*i == "data.txt")                                  
        execData();
    }
  return (0);
}

In that case, I stay on the first list "File.txt data.txt contact.txt" (cf: schema) and I can go through the second list "Search.txt employe.csv".

I've tried this too:

int     Parser::execCmd()
{
  std::list<std::pair<listStr, int> >::const_iterator i;

  for (i = _execCmd.begin(); i != _execCmd.end(); ++i)        
   {
     if (*i == "Search.txt")                                    
        execSearch();                                  
     else if (*i == "data.txt")                               
        execData();                           
   }
  return (0);
}

But I can't compile this because I don't know how to compare the iterator with a string (*i == "help")

Somebody can help me please ?

Upvotes: 0

Views: 2235

Answers (2)

Al.G.
Al.G.

Reputation: 4406

As I said in the comments, the way to iterate over an std::list in c++ is to use the foreach syntax.

The idea of an iterator is to give you a pointer-like access to elements in the container and to provide a way for the container to operate on these elements. For example, given an iterator you can delete an element in a list. Or you could insert an element at specific position.

What you need, however, is just to traverse over the list elements and check whether there is "search.txt" or "data.txt". So you don't need any iterators, you need just the elements. This is what the range-based for loop in c++ is. (Look at this great question: What is the correct way of using C++11's range-based for?)

Note that internally the range-based for loop internally may use iterators.

  std::list<std::pair<listStr, int> >::const_iterator i;

  for (std::pair<listStr, int> &elementFromOuterList: _execCmd) {
      // now given that elementFromOuterList you can do whatever you need to
  }

Upvotes: 0

Peter
Peter

Reputation: 36627

A std::pair<X,Y> contains two members, first which obtains the member of type X and second which obtains the member of type Y.

In your case, thanks to the typedef you have a std::list<std::pair<std::list<std::string>, int> >.

So to iterate over all std::strings in that structure, you need to iterate over the outer list to get the pairs, obtain the first member from each of those (of type std::list<string>, and iterate over ever element of that inner list.

int Parser::execCmd()
{
    std::list<std::pair<listStr, int> >::const_iterator i;

    for (i = _execCmd.begin(); i != _execCmd.end(); ++i)        
    {
        // i->first is of type std::list<std:string>

        for (j = i->first.begin(); j != i->first.end(); ++j)
        {
             if (*j == "Search.txt")                                    
                 execSearch();                                  
             else if (*j == "data.txt")                               
                 execData();                           
        }
   }
   return (0);
}

In C++11, it is simpler, but still necessary to nest loops.

int Parser::execCmd()
{
    std::list<std::pair<listStr, int> >::const_iterator i;

    for (const auto &i : _execCmd))        
    {
        // i.first is of type std::list<std:string>

        for (const auto &j : i.first)
        {
             if (j == "Search.txt")                                    
                 execSearch();                                  
             else if (j == "data.txt")                               
                 execData();                           
        }
   }
   return (0);
}

Upvotes: 1

Related Questions