Sam Walpole
Sam Walpole

Reputation: 1184

C# Sorting IEnumerable of IEnumerables

I have an object that looks something like this:

public class MyObj 
{
  public string Title { get; set; }
  public IEnumerable<Section> Sections { get; set; }
}

public class Section
{
  public string Title { get; set; }
  public IEnumerable<Item> Items { get; set; }
  public int SortOrder { get; set; }
}

public class Item
{
  public string Title { get; set; }
  public int SortOrder { get; set; }
}

Essentially I end up with an IEnumerable of sections, which in turn contains an IEnumerable of items. Both the list of sections and the items need to be sorted by their respective SortOrder properties.

I know that I can sort the sections by doing obj.Sections.OrderBy(s => s.SortOrder) but then I can't work out how to sort the items within each section too.

The context is that I'm writing a Sort function that takes an unsorted MyObj and returns one with both the sections and the items sorted.

public MyObj Sort(MyObj unsortedObj)
{
  var sortedObj = unsortedObj.....

  return sortedObj;
}

The expected data structure would be something like this:

- Section1
  - Item1
  - Item2
- Section2
  - Item1
  - Item2

Upvotes: 1

Views: 221

Answers (1)

Sweeper
Sweeper

Reputation: 271175

It would be convenient for you to add methods that creates copies of these objects except for one property being different:

// in MyObj
public MyObj WithSections(IEnumerable<Section> sections) =>
    new MyObj {
        Title = this.Title,
        Sections = sections
    };

// in Section
public Section WithItems(IEnumerable<Items> items) =>
    new Section {
        Title = this.Title,
        Items = items,
        SortOrder = this.SortOrder
    };

First, sort the sections

var sortedSections = unsortedObj.Sections.OrderBy(x => x.SortOrder);

Then for each of those sorted sections, transform them with Select so that their items are also sorted:

var sortedSectionsAndItems = sortedSections.Select(x => x.WithItems(x.Items.OrderBy(y => y.SortOrder)));

Now you can return a MyObj with the sorted sections and items:

return unsortedObj.WithSections(sortedSectionsAndItems);

Upvotes: 4

Related Questions