Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Linq expression to validate if list is ordered ascending or descending

Tags:

c#

linq

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?

like image 436
Mikk Avatar asked May 09 '14 10:05

Mikk


People also ask

How do I get data in descending order in LINQ?

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.

Is LINQ OrderBy ascending?

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.

What is any () in LINQ?

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.

Which LINQ method allows you to specify the number of items to return in a sequence?

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.


3 Answers

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.

like image 87
decPL Avatar answered Sep 21 '22 01:09

decPL


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");
like image 40
User 12345678 Avatar answered Sep 19 '22 01:09

User 12345678


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));
}
like image 40
Sergei Zinovyev Avatar answered Sep 17 '22 01:09

Sergei Zinovyev