C#自定义类按照自定义字段和值排序

 

 背景:

        产品提出需求,一个申请单需要客户自定义字段名和字段值进行排序,并且指定各个排序规则的优先级,如:先根据急诊和普诊排序然后再根据军人,普通人排序,然后再根据其他的规则排序。规则用户可以自定义。


实现:

    1:用户可以自定义类的字段名称并且可以自定义值的List<>,如:sex: “女”,"男"。

    2:用户第一定义多个1的规则,并有顺序

具体算法实现是:

 是采用每项打分的方法,因为规则有顺序,所以第一个规则较贵分值的粒度为1,下面的分值的粒度依次为0.1,0.01,0.001

那么背景中描述的第一个规则急诊和普诊规则分数依次为2和1,第二个规则军人和普通人分数依次为0.2和0.1等等依次类推

代码实现如下:

可以调用  new PaiXu().goTest();查看测试排序代码

 

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Text;

namespace AllTestProject
{
    public class PaiXu
    {
        private static readonly List<string> RankList = new List<string>() { "主席", "部长", "省长", "市长", "科长", "职员" };
        private static readonly List<string> SexList = new List<string>() { "女", "男", "未知" };
        private static readonly List<string> FeatureList = new List<string>() { "孕妇", "残疾人", "老人", "小孩", "普通人" };

        Dictionary<string, List<string>> propertyDictionary = new Dictionary<string, List<string>>()
        {
            {"Rank",RankList},
            {"Sex",SexList},
            {"Feature",FeatureList}
        };
        public static Random random = new Random(Guid.NewGuid().GetHashCode());

        public void goTest()
        {
            var cc = Sort<People>(getTestList());
        }
        private List<People> getTestList()
        {
            List<People> peoples = new List<People>();
            for (int i = 0; i < 100; i++)//造测试数据
            {
                peoples.Add(new People()
                {
                    Feature = FeatureList[random.Next(0, 5)],
                    Rank = RankList[random.Next(0, 6)],
                    Sex = SexList[random.Next(0, 3)]
                });
            }
            return peoples;
        }

        private IEnumerable<T> Sort<T>(List<T> peoples)
        {
            int peopleIndex = 0;
            var sortResList = new Dictionary<int, decimal>();//这个是最后的结果
            foreach (var people in peoples)
            {
                var peopleType = people.GetType();
                var sortNumList = new List<decimal>();
                foreach (var key in propertyDictionary.Keys)
                {
                    Trace.Assert(peopleType.GetProperty(key) != null);
                    var value = peopleType.GetProperty(key).GetValue(people, null).ToString();
                    decimal score = 0;
                    var itemIndex = propertyDictionary[key].FindIndex(a => a == value);//是否等于某个排序项
                    if (itemIndex < 0)
                    {
                        sortNumList.Add(0);
                    }
                    else
                    {
                        sortNumList.Add(propertyDictionary[key].Count - itemIndex);//这个是根据第一个应该是最靠前的,所以第一的下标是最大的
                    }
                }
                decimal interval = 1;
                decimal resDecimal = 0;
                foreach (var sortNum in sortNumList)
                {
                    resDecimal += sortNum * interval;
                    interval = interval * (decimal)0.1;
                }
                sortResList.Add(peopleIndex, resDecimal);
                peopleIndex++;
            }
            var newPeoples = new List<T>();
            foreach (int index in sortResList.OrderBy(a => a.Value).Select(a => a.Key).ToList())
            {
                newPeoples.Add(peoples[index]);
            }
            return newPeoples;
        }
    }

    public class People
    {
        /// <summary>
        /// 职级,主席,部长,省长,市长,科长,职员
        /// </summary>
        public string Rank { get; set; }
        /// <summary>
        /// 性别,女男未知
        /// </summary>
        public string Sex { get; set; }
        /// <summary>
        /// 老人小孩儿等属性
        /// </summary>
        public string Feature { get; set; }
    }
}
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值