Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Lambda Sort on Long Types

I'm trying to run a sort as below but am running into an issue with the Start properties being of type Long in the Lambda expression. When they were of type int this was working correctly but I need this to work over larger values. I've tried casting the a.Start - b.Start to int but this seems to provide an incorrect sort result.

Is there a different method by which I should be sorting or should I change datatypes?

ranges.Sort((a, b) => a.Start - b.Start);

enter image description here

private readonly List<Range> ranges = new List<Range>();
public class Range
{
    public Range(long startEnd) : this(startEnd, startEnd)
    {
    }

    public Range(long start, long end)
    {
        if (end >= start)
        {
            Start = start;
            End = end;
        }
        else
        {
            Start = end;
            End = start;
        }
    }

    public long Start { get; private set; }
    public long End { get; private set; }

    public void Update(long newStart, long newEnd)
    {
        Start = newStart;
        End = newEnd;
    }

    public static implicit operator Range(long i)
    {
        return new Range(i);
    }
}
like image 880
windowsgm Avatar asked Jan 28 '23 05:01

windowsgm


2 Answers

Function you pass to Sort should:

  • return anything negative if a < b (can be always -1 for example)
  • zero if a == b
  • anything positive if a > b (can be always 1 for example)

Your current function satisfies this criteria (but not safe to use because of potential overflow), but returns long. There are many other functions that satisfy this criteria though. One is already existing comparer for longs:

ranges.Sort((a, b) => a.Start.CompareTo(b.Start));

You can do the same yourself if you'd like (though no reason to):

ranges.Sort((a, b) => a.Start > b.Start ? 1 : a.Start < b.Start ? -1 : 0);
like image 75
Evk Avatar answered Feb 04 '23 21:02

Evk


The delegate you pass to the Sort method is a Comparison<T> which must always return an int, whatever the type T it is comparing.

The int returned from this delegate should be:

A signed integer that indicates the relative values of x and y, as shown in the following table.

Value             Meaning

Less than 0       x is less than y.

0                x equals y.

Greater than 0   x is greater than y.

Therefore the fact that it worked when your Start was an int is actually purely coincidental.

You can fix your case by having your delegate return

a.Start.CompareTo(b.Start)
like image 28
AakashM Avatar answered Feb 04 '23 23:02

AakashM