【问题标题】:Lambda Sort on Long Types长类型的 Lambda 排序
【发布时间】:2018-04-26 09:28:56
【问题描述】:

我正在尝试运行如下排序,但遇到了 Start 属性在 Lambda 表达式中属于 Long 类型的问题。当它们是 int 类型时,它可以正常工作,但我需要它来处理更大的值。我尝试将 a.Start - b.Start 转换为 int 但这似乎提供了不正确的排序结果。

我应该使用不同的方法进行排序还是应该更改数据类型?

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

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);
    }
}

【问题讨论】:

    标签: c# .net linq sorting


    【解决方案1】:

    你传递给Sort的函数应该:

    • 如果 a
    • 如果 a == b 则为零
    • 如果 a > b 则为正值(例如,可以始终为 1)

    您当前的函数满足此标准(但由于潜在的溢出,使用不安全),但返回 long。但是,还有许多其他功能可以满足此标准。一个是长期存在的比较器:

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

    如果你愿意,你也可以自己做(虽然没有理由):

    ranges.Sort((a, b) => a.Start > b.Start ? 1 : a.Start < b.Start ? -1 : 0);
    

    【讨论】:

      【解决方案2】:

      您传递给Sort 方法的委托是一个Comparison&lt;T&gt;,它必须总是返回一个int,无论它比较的是什么类型的T

      从这个委托返回的int应该是:

      一个有符号整数,表示 x 和 y 的相对值,如 如下表所示。

      Value             Meaning
      
      Less than 0       x is less than y.
      
      0                x equals y.
      
      Greater than 0   x is greater than y.
      

      因此,当您的 Startint 时它起作用的事实纯属巧合。

      您可以通过让您的代表返回来解决您的问题

      a.Start.CompareTo(b.Start)
      

      【讨论】:

        【解决方案3】:

        比较应该返回int,因此您需要以某种方式将long 转换为int。您可以 Convert.ToInt32 或者,如果可能超出范围,只需返回 -1 为任何负值,1 为任何正值。

        另一个可能更好的选择是使用intlong 的值之一的CompareTo 方法,这在功能上等同于第二个选项。

        【讨论】:

          【解决方案4】:

          a.Start - b.Start 转换为 int 似乎在这里可以工作,但是这样做会使自己暴露在溢出错误中(例如,如果 a.Start 为 0 且 b.Startlong.MaxValue 会怎样?)。由于Sort 只检查您的 lambda 是返回正值、负值还是零,所以您可以这样做:

          ranges.Sort((a, b) => a.Start > b.Start ? 1 : a.Start < b.Start ? -1 : 0);
          

          或者,LINQ 的OrderBy 工作得很好(并且不限于Lists),但请注意它返回一个新对象而不是修改原始对象,这对您来说可能合适,也可能不合适:

          ranges = ranges.OrderBy(r => r.Start).ToList()
          

          【讨论】:

            猜你喜欢
            • 2022-01-08
            • 2021-07-08
            • 1970-01-01
            • 2015-11-17
            • 2017-12-28
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多