定制订单,是否可能?

时间:2011-04-21 09:04:10

标签: c# linq

我有以下系列:

  

-3,-2,-1,0,1,2,3

我如何在单个order by语句中按以下形式对它们进行排序:

负数首先按其(绝对值)排序,然后按正数排序。

  

-1,-2,-3,0,1,2,3

4 个答案:

答案 0 :(得分:7)

组合排序,首先是符号,然后是绝对值:

list.OrderBy(x => Math.Sign(x)).ThenBy(x => Math.Abs(x));

或:

from x in list
orderby Math.Sign(x), Math.Abs(x)
select x;

这在概念上类似于SQL语句:

SELECT x
FROM list
ORDER BY SIGN(x), ABS(x)

在LINQ-to-Objects中,排序只执行一次,而不是两次。

警告:如果x == int.MinValue,Math.Abs​​(x)将失败。如果这个边缘情况很重要,那么你必须单独处理它。

答案 1 :(得分:6)

var numbers = new[] { -3, -2, -1, 0, 1, 2, 3 };

var customSorted = numbers.OrderBy(n => n < 0 ? int.MinValue - n : n);

这里的想法是将非负数与它们的值进行比较。并将负数与int.MinValue - n的值-2147483648 - n进行比较,因为n为负数,我们的负数越高,结果的结果就越低。

当列表本身包含数字int.MinValue时,它不起作用,因为它评估为0本身等于0。正如理查德所建议的那样,如果你需要全范围,可以使用long来制作,但性能会因此受到轻微影响。

答案 2 :(得分:0)

尝试类似(VB.Net示例)

Orderby(Function(x) iif(x<0, Math.Abs(x), x*1000))

...如果值<&lt; 1000

答案 3 :(得分:0)

您可以在LINQ中表达它,但如果我在两年后阅读代码,我更愿意看到类似的内容:

list.OrderBy(i=>i, new NegativeThenPositiveByAscendingAbsoluteValueComparer());

您需要实现IComparer。