How to use a C # delegate as a functor in C ++?

In C ++, to sort a vector, list, or any collection, I would use:

#include <iostream> #include <vector> #include <string> #include <algorithm> using namespace std; int main() { vector<int> vt; vt.push_back( 3 ); vt.push_back( 1 ); vt.push_back( 2 ); sort( vt.begin(), vt.end(), greater<int>() ); } 

In C #, I found List<> equivalent to std::vector<> :

 using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Professional_Csharp { class Program { static void Main( string[] args ) { List<int> intList = new List<int>(); intList.Add( 3 ); intList.Add( 2 ); intList.Add( 1 ); intList.Sort(); } } } 

This worked fine, however, if I want to set up a comparator, how can I implement this? Or, if I want to sort only a certain range, not the entire list? How could I do this?

Refresh

 sort( vt.begin(), vt.begin() + 1 ); 

Is this possible in C #?

Thanks,
Chan

+4
source share
6 answers

Within the .NET framework, you will sometimes find methods (such as Sorting) that have one or more overloads that accept additional types (interfaces or delegates) to extend their behavior. Unlike C ++, .NET does not have the same approach as STL for composite algorithms.

In the case of List.Sort there are two overloads that might be useful:

 List.Sort( IComparer<T> comparer ) // and List.Sort( Comparison<T> comparison ) // .NET 4.0 and up 

The first overload takes an instance of a type that implements IComparer<T> - an interface with a single Compare method. The second overload is only available if you are using .NET 4.0 or later โ€” it accepts a delegate (or lambda expression) that provides comparison semantics.

If you can, the second overload is much easier to use:

 intList.Sort( (a,b) => YourCompare(a,b) /* your compare logic here */ ); 

To use the first overload, you must create a class or structure that implements IComparer<T> :

 public sealed class YourComparer : IComparer<YourType> { int Compare( YourType a, YourType b ) { ... } } intList.Sort( new YourComparer() ); 

If you do not want to modify the collection yourself, but only sort its elements and operate on them as a new sequence, you can use LINQ OrderBy :

 intList.OrderBy( x => ... ).ToArray() /* creates new sequence, won't alter intList */ 

<h / "> To answer the second part of your question, if you want to sort only a certain range of a specific collection, you will have to use the Sort( int, int, IComparer<T> ) overload Sort( int, int, IComparer<T> ) .

+3
source

You can provide a comparison as a parameter for the sorting method: http://msdn.microsoft.com/en-us/library/w56d4y5z.aspx . I will give an example, but the MSDN article should be enough.

+2
source

List.Sort () has overloads that accept lambdas to do comparisons. For instance:

 public class ElementClass {public int A; public int B;} ... List<ElementClass> myList = GetAListOfRandomElementClassInstances(); //sorts in ascending order by A, then B myList.Sort((x,y)=> xA > yA ? 1 : xA < yA ? -1 : xB > yB ? 1 : xB < yB ? -1 : 0); 

List.Sort () will also take IComparer, allowing you to encapsulate custom sorting behavior:

 public class ElementClassComparer : IComparer<int> { public int Compare(int a, int b) { return xA > yA ? 1 : xA < yA ? -1 : xB > yB ? 1 : xB < yB ? -1 : 0 } } ... myList.Sort(new ElementClassComparer()); 

The Linq library also has an OrderBy () method that will sort by any IComparable projection:

 myList = myList.OrderBy(x=>xA).ThenBy(x=>xB).ToList(); 

This is a less effective, but much more readable version of the above varieties.

+2
source

You can use List<T>.Sort(IComparer<T>) and write your own IComparer. Documentation

+1
source

As already mentioned, List.Sort has several useful overloads. Here are just a few implementation examples.

IComparer <T>

 public class MyComparer : IComparer<int> { public int Compare(int x, int y) { return x - y; } } ... List<int> list = new List<int>(); // Example start/end indexes int startIndex = 0, endIndex = list.Count; // Use IComparer<T> MyComparer comparer = new MyComparer(); list.Sort(startIndex, endIndex, comparer); 

Comparison <T>

 static int MyCompareMethod(int x, int y) { return x - y; } ... // Use Comparison<T> list.Sort((x, y) => MyCompareMethod(x, y)); 
+1
source

Although my post is not trying to answer your question, as people have already said. So I would like to talk about an alternative.

Suppose you want to sort Person by age, then you can write the query as code:

 var sortedPersons = from person in persons where true orderby person.Age ascending select person; 

This syntax is very expressive and so attractive that I have recently started the next section on it.

What's fast: Query syntax versus loops

Check this.: -)

+1
source

Source: https://habr.com/ru/post/1338481/


All Articles