簡體   English   中英

將列表按升序和降序排序

[英]Sorting a list in ascending and descending order

我有一個整數的集合,例如

輸入示例

4,7,9,8,20,56,78,34,2,76,84,98

我需要對列表進行排序,直到任何數字til 20都將以升序排序,而大於20的數字將以降序排序。 因此輸出將是:

輸出示例

2,4,7,8,9,20,98,84,78,76,56,34

我為此寫了一個比較器。 但是現在嘗試使用更干凈的方法可能是使用現有的工具,例如orderby。

您可以使用兩個排序組來做到這一點:

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

您可以使用自定義比較器輕松地做到這一點:

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 因此,我並不是真的認為這不是“干凈”的,但是還不錯。

為什么不使用兩個步驟?

var bellow = originallist.Where(i => i <= 20).OrderBy(i);
var above= originallist.Where(i => i > 20).OrderByDescending(i);

var sorted = bellow.Concat(above).ToList();
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));
[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);
        }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM