Ackman
Ackman

Reputation: 1592

Groupby followed by orderby keeping the group intact and then sort individual group

This one seemed a little tough for me to do using LINQ. I have a list of alerts and an alert looks like:

 public short AlertTypeId { get; set; }
 public string Type { get; set; }
 public int Severity { get; set; }
 public bool IsOverview { get; set; }
 public string Title { get; set; }
 public string Text { get; set; }
 public int Position { get; set; }
 public string Id { get; internal set; }
  1. I want to first group these alerts by alertIDType,
  2. sort elements in an individual group by severity in desc and ...
  3. Then sort entire groups by the same alertIDType in a specific order (I have a utils sorter for that mentioned below)

The sorting code currently looks like:

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()
                }).ToList()
        };

        alerts.AllAlerts = alerts.AllAlerts.GroupBy(a => a.AlertTypeId)
                .OrderByDescending(g => Utils.AlertSorterUtil.SortByAlertTypeId(g.Key))
                .SelectMany(g => g.OrderByDescending(a => a.Severity)).ToList();

        // Alerts displayed on the overview page
        alerts.OverviewAlerts =
            alerts.AllAlerts
                .ToList()
                .Where(a => a.IsOverview && !string.IsNullOrEmpty(a.Title))
                .Take(3)
                .ToList();

Utils sorter method looks like:

public class AlertSorterUtil
{
    public static int SortByAlertTypeId(short alertTypeId)
    {
        var orderArray = new int[]
        {
            8106,   // Confirmed Out of Business
            8105,   // Bankruptcy
            8111,   // Lack of Licensing
            8109,   // Investigations
            8103,   // Government Actions
            8104,   // Pattern of Complaints
            8112,   // Customer Reviews
            8110,   // Accreditation
            8101,   // Misuse of BBB Name
            8107,   // Advisory
            8102,   // Advertising Review
        };

        for (int orderValue = 0; orderValue < orderArray.Length; orderValue++)
        {
            if (alertTypeId == orderArray[orderValue])
            {
                return orderValue;
            }
        }

        return int.MaxValue;
    }
}

Upvotes: 0

Views: 41

Answers (1)

Rashid Ali
Rashid Ali

Reputation: 617

Assuming you have a list of alerts to perform all these operations on. do the following with LINQ. It will group alerts by AlertTypeId then sort the groups by AlertTypeId and finally sort individual groups by Severity asc.

var groupedAlerts = alerts.GroupBy(a => a.AlertTypeId).OrderBy(g => Utils.AlertSorterUtil.SortByAlertTypeId(g.Key)).Select(g => g.OrderByDescending(a => a.Severity).ToList()).ToList();

Upvotes: 2

Related Questions