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?
CodePudding user response:
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.
CodePudding user response:
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);
CodePudding user response:
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();
CodePudding user response:
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.