在 C# 中按类型字段重新排列对象列表

我有一个传入的警报列表,我使用 MapFunction 作为:


private static BPAlerts MapToAlerts(List<IntakeAlert> intakeAlerts)

        {

            // Make sure that there are alerts

            if (intakeAlerts.IsNullOrEmpty()) return new BPAlerts { AllAlerts = new List<BPAlert>(), OverviewAlerts = new List<BPAlert>() };


            // All Alerts

            var alerts = new BPAlerts

            {

                AllAlerts = intakeAlerts.Select(

                    alert => new BPAlert

                    {

                        AlertTypeId = alert.AlertTypeId ?? 8100,

                        IsOverview = alert.IsOverviewAlert.GetValueOrDefault(),

                        Text = alert.AlertText,

                        Title = alert.AlertTitle,

                        Type = alert.AlertTypeId == 8106 ? "warning" : "report",

                        Severity = alert.AlertSeverity.GetValueOrDefault(),

                        Position = alert.Position.GetValueOrDefault()

                    }).OrderBy(a => a.Position).ToList()

            };



            // Alerts displayed on the overview page

            alerts.OverviewAlerts =

                alerts.AllAlerts

                    .ToList()

                    .Where(a => a.IsOverview && !string.IsNullOrEmpty(a.Title))

                    .Take(3)

                    .ToList();


            return alerts;

        }



我想要实现一个任务,其中 MaptoAlerts 函数返回一个警报对象,其中包含根据 BPAlert 类型排序的概述警报。如果存在的话,请按以下顺序更清楚:


确认停业 - 8106 \n 破产 - 8105 \n 缺乏许可 - 8111 \n 调查 - 8109 \n 政府行为 - 8103 \n 投诉模式 - 8104 \n 客户评论 - 8112 \n 认证 - 8110 \n 滥用BBB 名称 - 8101 \n 咨询 - 8107 \n 广告审查 - 8102 \n


繁花不似锦
浏览 88回答 2
2回答

冉冉说

解决方案 #1 订购值数组我只是在某种集合中定义这些 id 的顺序,可以是一个数组:var orderArray = new int[]{&nbsp; &nbsp; 8106,&nbsp; &nbsp;// Confirmed Out of Busine&nbsp; &nbsp; 8105,&nbsp; &nbsp;// Bankruptcy&nbsp; &nbsp; 8111,&nbsp; &nbsp;// Lack of Licensing&nbsp; &nbsp; 8109,&nbsp; &nbsp;// Investigations&nbsp; &nbsp; 8103,&nbsp; &nbsp;// Government Actions&nbsp; &nbsp; 8104,&nbsp; &nbsp;// Pattern of Complaints&nbsp; &nbsp; 8112,&nbsp; &nbsp;// Customer Reviews&nbsp; &nbsp; 8110,&nbsp; &nbsp;// Accreditation&nbsp; &nbsp; 8101,&nbsp; &nbsp;// Misuse of BBB Name&nbsp; &nbsp; 8107,&nbsp; &nbsp;// Advisory&nbsp; &nbsp; 8102,&nbsp; &nbsp;// Advertising Review};然后迭代数组,同时递增订单值。循环检查订单数组是否包含我正在尝试评估的订单值的实际类型 id:for (int orderValue = 0; orderValue < orderArray.Length; orderValue++){&nbsp; &nbsp; if (alertTypeId == orderArray[orderValue])&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; return orderValue;&nbsp; &nbsp; }}如果在数组中找不到,则返回可能的最大值:return int.MaxValue整个方法如下所示,它将评估警报类型 id 的顺序:public int GetAlertTypeIdOrder(short alertTypeId){&nbsp; &nbsp; var orderArray = new int[]&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; 8106,&nbsp; &nbsp;// Confirmed Out of Busine&nbsp; &nbsp; &nbsp; &nbsp; 8105,&nbsp; &nbsp;// Bankruptcy&nbsp; &nbsp; &nbsp; &nbsp; 8111,&nbsp; &nbsp;// Lack of Licensing&nbsp; &nbsp; &nbsp; &nbsp; 8109,&nbsp; &nbsp;// Investigations&nbsp; &nbsp; &nbsp; &nbsp; 8103,&nbsp; &nbsp;// Government Actions&nbsp; &nbsp; &nbsp; &nbsp; 8104,&nbsp; &nbsp;// Pattern of Complaints&nbsp; &nbsp; &nbsp; &nbsp; 8112,&nbsp; &nbsp;// Customer Reviews&nbsp; &nbsp; &nbsp; &nbsp; 8110,&nbsp; &nbsp;// Accreditation&nbsp; &nbsp; &nbsp; &nbsp; 8101,&nbsp; &nbsp;// Misuse of BBB Name&nbsp; &nbsp; &nbsp; &nbsp; 8107,&nbsp; &nbsp;// Advisory&nbsp; &nbsp; &nbsp; &nbsp; 8102,&nbsp; &nbsp;// Advertising Review&nbsp; &nbsp; };&nbsp; &nbsp; for (int orderValue = 0; orderValue < orderArray.Length; orderValue++)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; if (alertTypeId == orderArray[orderValue])&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return orderValue;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; return int.MaxValue;}用法:var sortedAlerts = alerts&nbsp; &nbsp; .AllAlerts&nbsp; &nbsp; .OrderByDescending(a => GetAlertTypeIdOrder(a.AlertTypeId))&nbsp; &nbsp; .ToList();它也以下降的方式工作。解决方案#2 订单值字典您可以通过减少冗余(重复创建存储顺序值的数组)来获得更好的性能。更好的主意是将顺序规则存储在字典中。我知道下面的代码也创建了一个数组,但概念是它将被调用一次以获取然后传递的字典。public Dictionary<int, int> GetOrderRules(){&nbsp; &nbsp; var alertTypeIds = new int[]&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; 8106,&nbsp; &nbsp;// Confirmed Out of Busine&nbsp; &nbsp; &nbsp; &nbsp; 8105,&nbsp; &nbsp;// Bankruptcy&nbsp; &nbsp; &nbsp; &nbsp; 8111,&nbsp; &nbsp;// Lack of Licensing&nbsp; &nbsp; &nbsp; &nbsp; 8109,&nbsp; &nbsp;// Investigations&nbsp; &nbsp; &nbsp; &nbsp; 8103,&nbsp; &nbsp;// Government Actions&nbsp; &nbsp; &nbsp; &nbsp; 8104,&nbsp; &nbsp;// Pattern of Complaints&nbsp; &nbsp; &nbsp; &nbsp; 8112,&nbsp; &nbsp;// Customer Reviews&nbsp; &nbsp; &nbsp; &nbsp; 8110,&nbsp; &nbsp;// Accreditation&nbsp; &nbsp; &nbsp; &nbsp; 8101,&nbsp; &nbsp;// Misuse of BBB Name&nbsp; &nbsp; &nbsp; &nbsp; 8107,&nbsp; &nbsp;// Advisory&nbsp; &nbsp; &nbsp; &nbsp; 8102,&nbsp; &nbsp;// Advertising Review&nbsp; &nbsp; };&nbsp; &nbsp; var orderRules = new Dictionary<int, int>();&nbsp; &nbsp; for (int orderValue = 0; orderValue < alertTypeIds.Length; orderValue++)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; orderRules.Add(alertTypeIds[orderValue], orderValue);&nbsp; &nbsp; }&nbsp; &nbsp; return orderRules;}因此该GetAlertIdOrder()方法看起来会有所不同,但仍然保留以前解决方案的想法:public int GetAlertIdOrder(short alertTypeId, IDictionary<int, int> orderRules){&nbsp; &nbsp; if (orderRules.TryGetValue(alertTypeId, out int orderValue))&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; return orderValue;&nbsp; &nbsp; }&nbsp; &nbsp; else&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; return int.MaxValue;&nbsp; &nbsp; }}用法:var orderRules = GetOrderRules();var sortedAlerts = alerts&nbsp; &nbsp; .AllAlerts&nbsp; &nbsp; .OrderBy(a => GetAlertIdOrder(a.AlertTypeId, orderRules))&nbsp; &nbsp; .ToList();

BIG阳

(a) 我不会将排序与映射器混合使用。让映射器做它自己的事情。(这是关注点分离).. 又名,没有排序/排序。恕我直言,你总是会在映射器中遇到太多难以理解的巫术。通过上面的代码,您已经走上了这条道路。(b) 如果“OverviewAlerts”是 AllAlerts 的子集(又名 AllAlerts 是超集),则水合 AllAlerts,并创建一个只读“get”属性,您可以在其中按其规则将 AllAlerts 筛选到您的子集。(可选)考虑 AllAlertsSorted get 属性。这样,您就可以让消费者选择是想要原始的还是排序的……因为排序是有成本的。public class BPAlerts&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; public List<BPAlert> AllAlerts { get; set; }&nbsp; &nbsp; &nbsp; &nbsp; public List<BPAlert> OverviewAlerts {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; get&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return null == this.AllAlerts ? null : this.AllAlerts.Where (do you filtering and maybe sorting here ) ;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; public List<BPAlert> AllAlertsSorted{&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; get&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return null == this.AllAlerts ? null : this.AllAlerts.Sort(do you filtering and maybe sorting here ) ;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }如果您执行只读属性,那么您将拥有更简单的 linq 操作,例如OrderBy(x => x.PropertyAbc).ThenByDescending(x => x.PropertyDef);我 99% 的映射代码都是这样的。如果您提供空输入,我什至不会抛出错误,我只是返回空。public static class MyObjectMapper {&nbsp; &nbsp; public static ICollection < MyOtherObject > ConvertToMyOtherObject(ICollection <MyObjectMapper> inputItems) {&nbsp; &nbsp; &nbsp; &nbsp; ICollection <MyOtherObject> returnItems = null;&nbsp; &nbsp; &nbsp; &nbsp; if (null != inputItems) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; returnItems = new List <MyOtherObject> ();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; foreach(MyObjectMapper inputItem in inputItems) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; MyOtherObject moo = new MyOtherObject();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; /* map here */&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; returnItems.Add(moo);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; return returnItems;&nbsp; &nbsp; }}
打开App,查看更多内容
随时随地看视频慕课网APP