按升序和降序对列表进行排序

时间:2016-06-16 14:27:12

标签: c# linq

我有一组整数,例如

输入示例

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。

5 个答案:

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