使用 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 委员会刚刚强加的顺序进行排序吗?
有关此主题的更多信息,请参阅我的系列文章;它从这里开始:
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 委员会刚刚强加的顺序进行排序吗?
有关此主题的更多信息,请参阅我的系列文章;它从这里开始: