如何检查 IEnumerable<T> 是否排序?



如何检查IEnumerable是否排序?

bool IsSorted<T>(IEnumerable<T> enumerable)
{
   ???
}

这种方法的一个示例可能是:

static bool IsSorted<T>(IEnumerable<T> enumerable) where T : IComparable<T> {
    T prev = default(T);
    bool prevSet = false;
    foreach (var item in enumerable) {
        if (prevSet && (prev == null || prev.CompareTo(item) > 0))
            return false;
        prev = item;
        prevSet = true;
    }
    return true;
}

适用于大多数内置类型,如数字或字符串,因为它们实现了 IComparable。

只需检查每个项目是否不少于前一个项目:

  public static partial class EnumerableExtensions {
    public static bool IsSorted<T>(this IEnumerable<T> source, 
                                   IComparer<T> comparer = null) {
      if (null == source)
        throw new ArgumentNullException("source");
      if (null == comparer)
        comparer = Comparer<T>.Default;
      if (null == comparer)
        throw new ArgumentException("No default comparer found.");
      T prior = default(T);
      bool first = true;
      foreach (var item in source) {
        if (!first && comparer.Compare(prior, item) > 0)
          return false;
        first = false;
        prior = item; 
      }
      return true;
    }
  }

这将检查升序或降序排序,而不仅仅是升序

   enum SortOrder
    {
        Unknown = 0,
        Ascending = 1,
        Descending = 2
    }
    static bool IsSorted<T>(IEnumerable<T> enumerable)
    {
        var enumerator = enumerable.GetEnumerator();
        // Empty Enumerable
        if (!enumerator.MoveNext())
            return true;
        SortOrder order = SortOrder.None;
        // First Item
        var last = enumerator.Current;
        while(enumerator.MoveNext())
        { 
            var result = Comparer<T>.Default.Compare(last, enumerator.Current);
            switch (order)
            {
                case SortOrder.Unknown:
                    if (result == 0)
                        break;
                    if(result == -1)
                        order = SortOrder.Ascending;
                    else 
                        order = SortOrder.Descending;
                    break;
                case SortOrder.Descending:
                    if (result == -1)
                        return false;
                    break;
                case SortOrder.Ascending:
                    if (result == 1)
                        return false;
                    break;
            }
            last = enumerator.Current;
        }

        return true;
    }

最新更新