I have a IEnumerable<DateTime>
var that I need to validate if it is sorted ascendingly or descendingly.
I can do this using a for loop but is there a way to do this using LINQ expression?
OrderByDescending Operator If you want to rearrange or sort the elements of the given sequence or collection in descending order in query syntax, then use descending keyword as shown in below example. And in method syntax, use OrderByDescending () method to sort the elements of the given sequence or collection.
In LINQ, the OrderBy operator is used to sort the list/ collection values in ascending order. In LINQ, if we use order by the operator by default, it will sort the list of values in ascending order.
The Any operator is used to check whether any element in the sequence or collection satisfy the given condition. If one or more element satisfies the given condition, then it will return true. If any element does not satisfy the given condition, then it will return false.
In LINQ, the Range method or operator is used to generate the sequence of integer or numbers based on the specified values of the start index and end index.
Ascending:
myEnumerable.Zip(myEnumerable.Skip(1), (curr, next) => curr <= next).All(x => x);
Descending:
myEnumerable.Zip(myEnumerable.Skip(1), (curr, next) => curr >= next).All(x => x);
But use a loop, LINQ is not a magic solution to everything.
var orderedByAsc = input.OrderBy(d => d);
if (input.SequenceEqual(orderedByAsc))
{
Console.WriteLine("Ordered by Asc");
return;
}
var orderedByDsc = input.OrderByDescending(d => d);
if (input.SequenceEqual(orderedByDsc))
{
Console.WriteLine("Ordered by Dsc");
return;
}
Console.WriteLine("not sorted");
LINQ extensions. Good candidates to MoreLinq library:
public static bool IsOrdered<T>(this IEnumerable<T> source, IComparer<T> comparer = null)
{
return source.IsOrdered(OrderByDirection.Ascending, comparer);
}
public static bool IsOrdered<T>(this IEnumerable<T> source, OrderByDirection direction, IComparer<T> comparer = null)
{
if (source == null)
{
throw new ArgumentNullException(nameof(source));
}
if (comparer == null)
{
comparer = Comparer<T>.Default;
}
int d = direction == OrderByDirection.Ascending ? 1 : -1;
Func<T, T, int> compareFunc= (i1, i2) => d * comparer.Compare(i1, i2);
return IsOrderedImpl(source, compareFunc);
}
public static bool IsOrdered<T>(this IEnumerable<T> source, Func<T, T, int> compareFunc)
{
if (source == null)
{
throw new ArgumentNullException(nameof(source));
}
if (compareFunc == null)
{
throw new ArgumentNullException(nameof(compareFunc));
}
return IsOrderedImpl(source, compareFunc);
}
private static bool IsOrderedImpl<T>(this IEnumerable<T> source, Func<T, T, int> compareFunc)
{
T prevItem = default(T);
int i = 0;
foreach (T item in source)
{
if (i == 0)
{
prevItem = item;
}
else
{
if (compareFunc(prevItem, item) > 0)
{
return false;
}
prevItem = item;
}
++i;
}
return true;
}
[TestMethod]
public void TestIsOrdered01()
{
Assert.IsTrue(Enumerable.Range(1, 10).IsOrdered());
Assert.IsFalse(Enumerable.Range(1, 10).Reverse().IsOrdered());
Assert.IsTrue(Enumerable.Range(1, 10).IsOrdered(OrderByDirection.Ascending));
Assert.IsFalse(Enumerable.Range(1, 10).IsOrdered(OrderByDirection.Descending));
Assert.IsFalse(Enumerable.Range(1, 10).Reverse().IsOrdered(OrderByDirection.Ascending));
Assert.IsTrue(Enumerable.Range(1, 10).Reverse().IsOrdered(OrderByDirection.Descending));
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With