我有一组整数,例如
输入示例
4,7,9,8,20,56,78,34,2,76,84,98
我需要对这个列表进行排序,任何数字直到20将按升序排序,而20以上的数字将按降序排序。所以输出将是:
输出示例
2,4,7,8,9,20,98,84,78,76,56,34
我为它写了一个比较器。但现在尝试更清洁的方法可能是使用现有的工具,如orderby。
答案 0 :(得分:6)
您可以使用两个排序组来执行此操作:
list.OrderBy(i => i <= 20 ? i : int.MaxValue) // sort numbers less than 20 ascending; put numbers greater than 20 at the end
.ThenByDescending(i => i) // sort remaining numbers descending
答案 1 :(得分:4)
您可以使用自定义比较器轻松完成此操作:
public class MyCustomComparer : IComparer<int>
{
private readonly int _cutOffPointInclusive;
public MyCustomComparer(int cutOffPointInclusive)
{
_cutOffPointInclusive = cutOffPointInclusive;
}
public int Compare(int x, int y)
{
if (x <= _cutOffPointInclusive || y <= _cutOffPointInclusive)
{
return x.CompareTo(y);
}
else
{
return y.CompareTo(x);
}
}
}
当要比较的任何一个值低于或等于截止点(两者都将较大的值推到顶部并将值排序到截止点上升时),并且当两者都大于截止点(实际上对这些较大值进行实际排序)。
使用:
进行测试var testData = new List<int>{ 4,7,9,8,20,56,78,34,2,76,84,98 };
testData.Sort(new MyCustomComparer(20));
foreach (var i in testData)
{
Console.WriteLine(i);
}
输出:
2
4
7
8
9
20
98
84
78
76
56
34
另见http://ideone.com/YlVH8i。所以我并不认为这不是&#34;干净&#34;,但是很好。
答案 2 :(得分:1)
为什么不使用两个步骤?
var bellow = originallist.Where(i => i <= 20).OrderBy(i);
var above= originallist.Where(i => i > 20).OrderByDescending(i);
var sorted = bellow.Concat(above).ToList();
答案 3 :(得分:0)
int[] a = { 4, 7, 9, 8, 20, 56, 78, 34, 2, 76, 84, 98 };
var b = a.OrderBy(i => i > 20 ? int.MaxValue - i : i);
如果可能,我建议就地排序。例如(可以改进)
Array.Sort(a, (i1, i2) => (i1 > 20 ? int.MaxValue - i1 : i1) - (i2 > 20 ? int.MaxValue - i2 : i2));
答案 4 :(得分:-1)
[Test]
public void SortTill20AscRestDesc()
{
var src = new[] {4, 7, 9, 8, 20, 56, 78, 34, 2, 76, 84, 98};
var expected = new[] {2, 4, 7, 8, 9, 20, 98, 84, 78, 76, 56, 34};
var result = src
.Select(
i => new
{
IsAbove20 = i > 20,
Value = i
}
)
.OrderBy(e => e.IsAbove20)
.ThenBy(e => e.IsAbove20 ? int.MaxValue : e.Value)
.ThenByDescending(e => e.Value)
.Select(e=>e.Value);
Assert.That(result.SequenceEqual(expected), Is.True);
}