0

I would like to sort lists with structures by certain fields/properties of structures. For example there is a structure:

public struct Some
{
    public int index;
    public DateTime date;
}

Do I have an opportunity to sort such a structure by two parameters simultaneously using the existing methods? Say, at the top of the list of such structures place those that will have the latest date and the largest index. Is it possible to sort simultaneously taking into account these two parameters?

1
  • afaik, you should choose one main criterion first using OrderBy then use ThenBy for the second. Commented May 8, 2022 at 12:42

4 Answers 4

3

Yes you can using LINQ

with the OrderBy method

OrderBy and ThenBy are the mothods you need.

Example:

list.OrderBy(x => x.index).ThenBy(x => x.date)

If you add Descending you can also sort it the other way round.

Sign up to request clarification or add additional context in comments.

Comments

1

Use custom sort comparison function.

Example 1:

    public struct MyItem
    {
        public int index;
        public DateTime date;
    }
    class Program
    {
        static void Main(string[] args)
        {
            var items = new MyItem[]{
                new MyItem{index=9, date=DateTime.Now},
                new MyItem{index=4, date=DateTime.Now},
                new MyItem{index=3, date=DateTime.Now},
                new MyItem{index=5, date=DateTime.Now},
                new MyItem{index=5, date=DateTime.Now + TimeSpan.FromDays(1)},
                new MyItem{index=6, date=DateTime.Now},
            };
            // sort by index, if equal then sort by date
            Array.Sort(items, (x, y) =>
            {
                if (x.index == y.index)
                    return x.date.CompareTo(y.date);
                return x.index.CompareTo(y.index);
            });

            foreach (var item in items)
                Console.WriteLine($"{item.index} {item.date}");
        }
    }

Example 2:

var items = new List<MyItem>{
    new MyItem{index=9, date=DateTime.Now},
    new MyItem{index=4, date=DateTime.Now},
    new MyItem{index=3, date=DateTime.Now},
    new MyItem{index=5, date=DateTime.Now},
    new MyItem{index=5, date=DateTime.Now + TimeSpan.FromDays(1)},
    new MyItem{index=6, date=DateTime.Now},
};
// sort by index, if equal then sort by date
items.Sort((x, y) => x.index.CompareTo(y.index) == 0 ? x.date.CompareTo(y.date) : x.index.CompareTo(y.index));

Example3: Linq

            var items = new List<MyItem>{
                new MyItem{index=9, date=DateTime.Now},
                new MyItem{index=4, date=DateTime.Now},
                new MyItem{index=3, date=DateTime.Now},
                new MyItem{index=5, date=DateTime.Now},
                new MyItem{index=5, date=DateTime.Now + TimeSpan.FromDays(1)},
                new MyItem{index=6, date=DateTime.Now},
            };
            // sort by index, if equal then sort by date
            var newItems = items.OrderBy(x => x.index).ThenBy(x => x.date);

Comments

1

If you want to Sort in place and you don't want to implement IComparable<Some> or IComparer<Some>:

List<Some> myList = ...

...

myList.Sort((left, right) => {
  // latest dates on the top (note - for descending sorting)
  int result = -left.date.CompareTo(right.date);

  // on tie when left and right have the same date we compare indexes
  return result == 0 
    ? -left.index.CompareTo(right.index)
    :  result; 
});

In case you have several fragments where you want to sort list in such a way, you can implement a comparer:

public sealed class SomeComparer : IComparer<Some> { 
  public int Compare(Some left, Some right) {
    // latest dates on the top (note - for descending sorting)
    int result = -left.date.CompareTo(right.date);

    // on tie when left and right have the same date we compare indexes
    return result == 0 
      ? -left.index.CompareTo(right.index)
      :  result;
  }
} 

Then whenever you want to sort the list:

myList.Sort(new SomeComparer());

Finally, if it's the only order you want to sort Some items, you can make Sort comparable:

public struct Some : IComparable<Some>
{
    public int index;
    public DateTime date;

    //TODO: implement Equals and GetHashCode 

    public bool CompareTo(Some other) {
      int result = -date.CompareTo(other.date);

      return result == 0 
        ? -index.CompareTo(other.index)
        : result;
    }
}

and you can put

myList.Sort();

Comments

0

You can use LINQ to easily sort items in a list by the values contained in a that list.

using System.Linq;

...

myStructs.OrderBy(s => s.index).ThenBy(s => s.date)

Will put everything in order by index. Items with equal index would be sorted by date.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.