博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

为List添加排序的函数 处理并列排名情况(下篇)

Posted on 2009-05-21 14:39  陈 亮  阅读(3379)  评论(6编辑  收藏  举报

上篇文章中 我们完成了动态创建类型  、动态设置值 、动态获取值  动态获取属性和返回值的一些方法

准备工作完成了.. 我们现在来完成排序的功能

实现方式肯定还是扩展方法..

实现比较2个值的方法 我们可以给用户提供. 我们不提供比较的方法 这样设计灵活性更好..

用户提供方法?? 怎么实现  很简单  2种方式  一种使用接口.. 另外一种使用的是委托..

我比较喜欢委托  我就使用委托的方式 .NET 中有预定于的委托 Comparison<T> 类型的委托  当然.NET 也定义了IComparer<T>接口作用也是一样的

方法定义了2个参数.. 一个是比较值的委托.. 还有个是获取名称的字段...  具体名次计算就比较简单了...

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); 
// 排序  Sort方法排序后的结果是升序
            
//反转List中的数据  就变成降序了
            list.Reverse();
            List
<object> returnlist = new List<object>();
            
int order = 1;
            
int pcount = 0;
            
//构造一个动态类型
            Dictionary<stringstring> 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中
                Dictionary<stringobject> tempRank = DynamicGetProperty(list[i]);
                
//添加名次的属性和值
                tempRank.Add(orderColumn, order);//添加名次和

                returnlist.Add(DynamicSetProperty(type, tempRank));
                
if (i < list.Count - 1)
                {
                    
//获得比较的结果
                    int t = i + 1;
                    
int result = comparsion(list[i], list[t]);

                    
if (result != 0)
                    {
                        
if (pcount == 0)
                        {
                            order
++;
                        }
                        
else
                        {
                            order 
= order + 1 + pcount;
                            pcount 
= 0;
                        }

                    }
                    
else
                    {
                        pcount
++;
                    }
                }

            }
            
return returnlist;
        }

这样就完成了自定义排序的方法

我们来看看使用效果

实体类

public class CityInfo
{
    
public string City { getset; }

    
public float Salary { getset; }
}

绑定

 if (!IsPostBack)
        {
            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();

 

前台代码

 

<asp:GridView ID="GridView1" runat="server" BackColor="White" Width="40%" 
            BorderColor
="#67DB4A" BorderStyle="None" BorderWidth="1px" CellPadding="4">
            
<RowStyle BackColor="White" ForeColor="#003399" />
            
<FooterStyle BackColor="#99CCCC" ForeColor="#003399" />
            
<PagerStyle BackColor="#99CCCC" ForeColor="#003399" HorizontalAlign="Left" />
            
<SelectedRowStyle BackColor="#009999" Font-Bold="True" ForeColor="#CCFF99" />
            
<HeaderStyle BackColor="#003399" Font-Bold="True" ForeColor="#CCCCFF" />
        
</asp:GridView>

 

显示效果

City Salary 位次
杭州 8000 1
上海 8000 1
北京 6000 3
广州 6000 3
深圳 4000 5
武汉 2000 6
成都 2000 6