首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> 關於C#

List 擴充排序功能:優雅處理並列排名(下篇)

     編輯:關於C#

承接上篇,我們已完成動態型別建立、屬性存取等基礎設施,現在要實作支援並列排名的擴充方法 Rank。設計上採用委派 Comparison<T> 讓呼叫端自訂比較邏輯,靈活度最高。

Rank 擴充方法實作

方法簽名:

public static IEnumerable<object> Rank<T>(
    this IEnumerable<T> value,
    Comparison<T> comparison,
    string orderName) where T : class

核心邏輯:

  1. 將來源轉為 List<T> 並依委派排序(預設升序),再 Reverse() 變降序。
  2. 動態建立新型別,包含原所有屬性加上排名欄位(預設名「Rank」,可自訂)。
  3. 迭代排序後清單,計算排名:相同值給予相同名次,下一名次跳過並列數量(如 1,1,3,3,5)。
  4. 透過反射將原物件屬性值與新排名寫入動態型別實例,回傳 IEnumerable<object>。

完整程式碼

public static IEnumerable<object> Rank<T>(this IEnumerable<T> value, Comparison<T> comparsion, string orderName) where T : class
{
    string orderColumn = "Rank";
    if (!string.IsNullOrEmpty(orderName)) orderColumn = orderName;

    List<T> list = value.ToList<T>();
    list.Sort(comparsion); // 升序
    list.Reverse();        // 降序

    List<object> returnlist = new List<object>();
    int order = 1;
    int pcount = 0;

    // 動態建立型別:原屬性 + 排名欄位
    Dictionary<string, string> dictionarytype = TypeTransform(typeof(T));
    dictionarytype.Add(orderColumn, typeof(int).FullName);
    Type type = DynamicCreateType(dictionarytype, new string[] { "System.dll", "System.Core.dll" });

    for (int i = 0; i < list.Count; i++)
    {
        Dictionary<string, object> tempRank = DynamicGetProperty(list[i]);
        tempRank.Add(orderColumn, order);
        returnlist.Add(DynamicSetProperty(type, tempRank));

        if (i < list.Count - 1)
        {
            int result = comparsion(list[i], list[i + 1]);
            if (result != 0)
            {
                if (pcount == 0) order++;
                else { order = order + 1 + pcount; pcount = 0; }
            }
            else pcount++;
        }
    }
    return returnlist;
}

實際應用範例

定義城市薪資類別:

public class CityInfo
{
    public string City { get; set; }
    public float Salary { get; set; }
}

呼叫 Rank 並繫結至 GridView:

var s = new List<CityInfo> {
    new CityInfo(){ City = "上海", Salary=8000f },
    new CityInfo() { City = "杭州", Salary=8000f },
    new CityInfo() { City = "北京", Salary=6000f },
    new CityInfo() { City = "廣州", Salary=6000f },
    new CityInfo() { City = "深圳", Salary=4000f },
    new CityInfo() { City = "成都", Salary=2000f },
    new CityInfo() { City = "武漢", Salary=2000f }
};

this.GridView1.DataSource = s.Rank<CityInfo>((c, c1) => c.Salary.CompareTo(c1.Salary), "位次");
this.GridView1.DataBind();

輸出結果正確處理並列:

CitySalary位次
杭州80001
上海80001
北京60003
廣州60003
深圳40005
武漢20006
成都20006

此擴充方法泛用性強,可套用於任何實作 class 的集合,且排名邏輯符合 SQL RANK() 語意。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved