Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
800 views
in Technique[技术] by (71.8m points)

linq - Native C# support for checking if an IEnumerable is sorted?

Is there any LINQ support for checking if an IEnumerable<T> is sorted? I have an enumerable that I want to verify is sorted in non-descending order, but I can't seem to find native support for it in C#.

I've written my own extension method using IComparables<T>:

public static bool IsSorted<T>(this IEnumerable<T> collection) where T : IComparable<T>
{
   Contract.Requires(collection != null);

   using (var enumerator = collection.GetEnumerator())
   {
      if (enumerator.MoveNext())
      {
         var previous = enumerator.Current;

         while (enumerator.MoveNext())
         {
            var current = enumerator.Current;

            if (previous.CompareTo(current) > 0)
               return false;

            previous = current;
         }
      }
   }

   return true;
}

And one using an IComparer<T> object:

public static bool IsSorted<T>(this IEnumerable<T> collection, IComparer<T> comparer)
{
   Contract.Requires(collection != null);

   using (var enumerator = collection.GetEnumerator())
   {
      if (enumerator.MoveNext())
      {
          var previous = enumerator.Current;

         while (enumerator.MoveNext())
         {
            var current = enumerator.Current;

            if (comparer.Compare(previous, current) > 0)
                return false;

            previous = current;
         }
      }
   }

   return true;
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You can check if collection is IOrderedEnumerable but that will work only if ordering is the last operation which was applied to sequence. So, basically you need to check all sequence manually.

Also keep in mind, that if sequence is IOrderedEnumerable you really can't say which condition was used to sort sequence.


Here is generic method which you can use to check if sequence is sorted in ascending order by field you want to check:

public static bool IsOrdered<T, TKey>(
    this IEnumerable<T> source, Func<T, TKey> keySelector)
{
    if (source == null)
        throw new ArgumentNullException("source");

    var comparer = Comparer<TKey>.Default;
    using (var iterator = source.GetEnumerator())
    {
        if (!iterator.MoveNext())
            return true;

        TKey current = keySelector(iterator.Current);

        while (iterator.MoveNext())
        {
            TKey next = keySelector(iterator.Current);
            if (comparer.Compare(current, next) > 0)
                return false;

            current = next;
        }
    }

    return true;
}

Usage:

string[] source = { "a", "ab", "c" };
bool isOrdered = source.IsOrdered(s => s.Length);

You can create similar IsOrderedDescending method - just change checking comparison result to comparer.Compare(current, next) < 0.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...