C# lambda expressions and IComparer

前端 未结 4 910
闹比i
闹比i 2021-02-04 03:15

I am using lambda expressions to sort and search an array in C#. I don\'t want to implement the IComparer interface in my class, because I need to sort and search on multiple m

相关标签:
4条回答
  • 2021-02-04 03:37

    if you want to avoid using external libraries, another option for you would be to first filter out the array and object. e.g.

    int index = Array.BinarySearch(
      widgets.Select(x=>x.foo).ToArray(),
      x.foo)
    
    0 讨论(0)
  • 2021-02-04 03:41

    Try this:

    public static class ComparisonEx
    {
        public static IComparer<T> AsComparer<T>(this Comparison<T> @this)
        {
            if (@this == null)
                throw new System.ArgumentNullException("Comparison<T> @this");
            return new ComparisonComparer<T>(@this);
        }
    
        public static IComparer<T> AsComparer<T>(this Func<T, T, int> @this)
        {
            if (@this == null)
                throw new System.ArgumentNullException("Func<T, T, int> @this");
            return new ComparisonComparer<T>((x, y) => @this(x, y));
        }
    
        private class ComparisonComparer<T> : IComparer<T>
        {
            public ComparisonComparer(Comparison<T> comparison)
            {
                if (comparison == null)
                    throw new System.ArgumentNullException("comparison");
                this.Comparison = comparison;
            }
    
            public int Compare(T x, T y)
            {
                return this.Comparison(x, y);
            }
    
            public Comparison<T> Comparison { get; private set; }
        }
    }
    

    It lets you use this code:

    Comparison<int> c = (x, y) => x == y ? 0 : (x <= y ? -1 : 1);
    IComparer<int> icc = c.AsComparer();
    
    Func<int, int, int> f = (x, y) => x == y ? 0 : (x <= y ? -1 : 1); 
    IComparer<int> icf = f.AsComparer();
    
    0 讨论(0)
  • 2021-02-04 03:44

    You can use my ValueComparer<T> class:

    int index = Array.BinarySearch(
        widgets, x,
        new ValueComparer<Widget>(x => x.Foo)
    );
    

    You can compare by multiple properties by passing multiple lambda expressions.

    0 讨论(0)
  • 2021-02-04 03:54

    Well, one option is to create something like ProjectionComparer instead. I've got a version of that in MiscUtil - it basically creates an IComparer<T> from a projection.

    So your example would be:

    int index = Array.BinarySearch(widgets, x,
                                   ProjectionComparer<Widget>.Create(x => x.foo));
    

    Or you could implement your own extension methods on T[] to do the same sort of thing:

    public static int BinarySearchBy<TSource, TKey>(
        this TSource[] array,
        TSource value,
        Func<TSource, TKey> keySelector)
    {
        return Array.BinarySearch(array, value,
                                  ProjectionComparer.Create(array, keySelector));
    }
    
    0 讨论(0)
提交回复
热议问题