使用 float + Lambda 表达式 C#

using float + Lambda Expressions C#

var distances = new Dictionary<char, float>();
var nodes = new List<char>();

我有这条线来求最小距离

nodes.Sort((x, y) => distances[x] - distances[y]);

当我使用 int 时效果很好,但是当我使用 float 时我收到一条消息

cannot convert lambda expression to type 'System.Collections.Generic.IComparer' because it is not a delegate type

你有想法吗?

您不能将您的 lambda 表达式转换为 Comparison<char>(这是您想要的),因为它 returns 是 float - 您实际上得到了 Func<char, char, float> 那里,而 Comparison<char> 更接近 Func<char, char, int>.

最简单的方法是使用 float.CompareTo:

nodes.Sort((x, y) => distances[x].CompareTo(distances[y]));

或者如果您不需要就地排序,您可以使用 LINQ:

var sorted = nodes.OrderBy(x => distances[x]);

重新制定 lambda 表达式如下。

nodes.Sort((x, y) =>
  {
    float Result = distances[x] - distances[y];
    if ( Result > 0.0f )
      return 1;
    else if ( Result < 0.0f )
      return -1;
    else
      return 0;
  });

首先,当值为整数时,您的原始程序是一种糟糕的编程习惯。它适用于字符,但我会避免这种糟糕的编程习惯。

您传递给排序函数的委托必须具有多个属性;特别是它必须 return 如果 x 小于 y 则为负整数,如果 x 大于 y 则为正整数,如果它们相等则为零。您的原始 lambda 不会对整数值执行此操作。 (看看你是否能找到两个整数 x 和 y,使得 x 小于 y 但 x - y 为正数。)

代表还必须施加总订单。总订单数:

  • 传递性必须成立。如果 A == B 且 B == C,则 A 必须等于 C。如果 A < B 且 B < C,则 A 必须小于 C。依此类推。
  • 一定是反对称的。也就是说,如果 A < B,则 B > A,依此类推。

整数减法不满足这些条件。正确的代码是实际写一个比较。

nodes.Sort((x, y) => x < y ? -1 : (x > y ? 1 : 0));

这对字符和浮点数很有效,前提是没有 NaN。如果你有 NaN,那么你需要做额外的工作来强加总顺序。

我还要指出,字符的这种序数比较通常不是您想要的比较。当然,这会正确地注意到 e 小于 z,但是简单的序数比较也表明 z 小于 é,这可能不是您想要的。字符顺序取决于文化;您确定要按照 Unicode 委员会刚刚强加的顺序进行排序吗?

有关此主题的更多信息,请参阅我的系列文章;它从这里开始:

http://ericlippert.com/2011/01/20/bad-comparisons-part-one/