本地C#支持检查IEnumerable是否已排序?

Mik*_*und 4 c# linq sorted icomparable sortedlist

是否有任何LINQ支持检查是否IEnumerable<T>已排序?我有一个我想要验证的枚举按非降序排序,但我似乎无法在C#中找到它的本机支持.

我使用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;
}
Run Code Online (Sandbox Code Playgroud)

一个使用IComparer<T>对象:

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;
}
Run Code Online (Sandbox Code Playgroud)

Ser*_*kiy 5

您可以检查集合是否存在,IOrderedEnumerable但只有在排序是应用于序列的最后一个操作时才会起作用.所以,基本上你需要手动检查所有序列.

还要记住,如果序列是IOrderedEnumerable你真的不能说哪个条件用于排序序列.


以下是通用方法,您可以使用它来检查序列是否按要检查的字段按升序排序:

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;
}
Run Code Online (Sandbox Code Playgroud)

用法:

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

您可以创建类似的IsOrderedDescending方法 - 只需将检查比较结果更改为comparer.Compare(current, next) < 0.