4

In C# given a struct:

struct Point {int x, int y}

We can write something like:

List<Point> list;
list.OrderBy(p => p.x).ThenBy(q => q.y);

How can I express this logic in C++ using lambda functions?

2
  • 1
    So you want to sort by x and then by y? Commented Jan 10, 2018 at 8:16
  • @GauravSehgal Yes. Commented Jan 10, 2018 at 8:21

4 Answers 4

8

It looks too me like you want a lexicographic sort on (y, x)1. You can leverage the library function std::tie. That one returns a tuple of references, and a std::tuple has a less-than operator which performs lexicographic comparison. So you only need to specify the order in which you want the items compared.

Here's how it would look for std::vector (your go to container type in C++, always start with std::vector):

std::vector<Point> my_list;
// Fill my_list
std::sort(begin(my_list), end(my_list), [](auto const& l, auto const& r){
  return std::tie(l.y, l.x) < std::tie(r.y, r.x);
});

1 - I'm basing this on the method names only, so this may not be what you are really after.

Sign up to request clarification or add additional context in comments.

5 Comments

Python lists are more similar to C++ vectors than linked lists.
@n.m.- What about C# lists? The OP asked based on that. I'm not familiar with C# too well myself.
According to here, apparently the same...
@Aconcagua - Amended answer accordingly. Thank you!
My bad, assumed Python wrongly but apparently C# lists are also more like vectors.
1

You can use STL function std::sort. Example:

struct point{
    int x;
    int y;
};

// Compare function. This can be lambda function too.
bool comp(const point& a,const point& b){ 
    if(a.x > b.x) return true;
    else if(a.x == b.x) return a.y > b.y;
    return false;
}


int main(){    
    // v is vector (or any other container which can be iterated) containing points
    std::sort(v.begin(),v.end(),comp);
}

7 Comments

You just sorted by x in this way. You should add If(a.x==b.x) return a.y>b.y; i guess.
Yes. I just wrote some dummy compare function. But I will add the code as per your suggestion for clarity.
((a.x > b.x) and (a.y > b.y)) is a wrong and dangerous comparison, not suitable for sorting.
@n.m. It would be great if you can explain me a bit on when can it go wrong.
Consider the case where a.x > b.x, but a.y < b.y. Your function will return false for both comp(a, b) and comp(b, a), which indicates that a and b should be considered equal. But they clearly should not.
|
1

Two ways - either you sort twice, first by y, then use a stable sort on x (be aware that this is exactly inverse as in C#!). Bad luck with std::sort, though, as it is not stable, fortunately, as Benjamin hinted to, there is std::stable_sort, too...

The other way is making sure that two points compare such that a difference in x applies first and only in case of equality, y is considered:

std::sort
(
    // range to sort
    list.begin(), list.end(),
    // next the comparator - you wanted a lambda? OK, here it is:
    [](point const& a, point const& b)
    {
        return a.x < b.x || a.x == b.x && a.y < b.y;
    }
);

2 Comments

std::sort may not be stable, but there is another function in the standard library that is. Curiously named std::stable_sort.
@BenjaminLindley Thanks for the hint. Didn't cope much for the first approach as I consider the second one superior anyway...
0

You just need to specify the lambda function to std::list::sort().You decide how you want to sort.

list.sort([](Point  i,Point  j)
            {
               if(i.x!=j.x)
                   return i.x<j.x;
               else
                   return i.y<j.y;
             }
          );

2 Comments

You'd better use const Point &
@user2807083 Actually no, in this case Point is sizeof == 8 on x64 systems, so copying it is better than using a reference

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.