user1313361
user1313361

Reputation: 1

Sorting with a list iterator

Problem: I have a list of objects I want to render every cycle, but I would like to render them in the order of their y- positions which is variable.

Here are my list declarations...

std::list<Object *> objects;
std::list<Object *>::iterator iter;
std::list<Object *>::iterator iter2;

Here is what I have so far...

for(iter = objects.begin(); iter != objects.end(); ++iter) //goes through my objs
   if((*iter)->GetID() == PLAYER || (*iter)->GetID() == ENEMY) //only part of the list
      for(iter2 = iter; iter2 != objects.end(); ++iter2) //goes through the same objs
         if((*iter2)->GetID() == PLAYER || (*iter2)->GetID() == ENEMY) //same as line 2
            if((*iter)->GetY() > (*iter2)->GetY())

I want to render the objects in decreasing order of their y-values. I guess my real question is how I would sort this list.

Upvotes: 0

Views: 2757

Answers (2)

Jerry Coffin
Jerry Coffin

Reputation: 490218

First, why are you using a list? It's virtually always a poor choice. Why are you using a container of pointers? There's good reason for that a little more often than using list, but we're still only talking about .05 percent of the time instead of .02 percent. Who knows -- in this case it might even work out for the best.

Anyway, we'll assume for the moment that those really make some sense for some reason. I'm also going to assume you can't modify the original collection (not clear whether this is true -- if not, just skip copying it, and sort the original collection -- but if you didn't need to maintain the order for some reason, it's nearly certain didn't really want a list.

Under those assumptions, you probably want to copy the collection, sort that, then present:

struct descY { 
    bool operator()(Object const *a, Object const *b) { 
        return b.GetY() < a.GetY();
    }
};

std::vector<Object *> sorted(objects.begin(), objects.end());
std::sort(sorted.begin(), sorted.end(), descY());

If you have C++11 available, you can use a lambda to shorten that a bit and keep the logic where it's a bit easier to see what's going on without chasing around the code to find the comparison:

std::vector<Object *> sorted(objects.begin(), objects.end());
std::sort(sorted.begin(), sorted.end(), 
          [](Object const *a, Object const *b) { return b->GetY() < a->GetY();});

Note that to get descending order, we're reversing the usual order in the comparison.

Upvotes: 2

Benjamin Lindley
Benjamin Lindley

Reputation: 103713

std::list has a sort function to which you can pass a comparator, so write one of those like this:

bool compareByGreaterY(const Object * lhs, const Object * rhs)
{
    return lhs->GetY() > rhs->GetY();
}

Then you can sort the list like this:

objects.sort(compareByGreaterY);

Upvotes: 4

Related Questions