Linq表达式,用于validation列表是按升序还是降序排序

我有一个IEnumerable var,我需要validation它是按升序还是降序排序。

我可以使用for循环来做到这一点,但有没有办法使用LINQ表达式?

 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"); 

上升:

 myEnumerable.Zip(myEnumerable.Skip(1), (curr, next) => curr <= next).All(x => x); 

降:

 myEnumerable.Zip(myEnumerable.Skip(1), (curr, next) => curr >= next).All(x => x); 

但是使用循环,LINQ并不是一切的神奇解决方案。

如果您确定该列表是有序的,那么您可以简单地比较列表的第一个和最后一个元素,以查看它是按升序还是降序排列。

这可能是过度设计,但希望教育和一些使用!

 public enum SortedState { NoValues, Undecided, Ascending, Descending, Mixture }; public class AscOrDescHelper where T : IComparable { SortedState state; T lastValue; bool uniqueValues; public AscOrDescHelper() { state = SortedState.NoValues; uniqueValues = true; // tentative assumption } public AscOrDescHelper ProcessNextValue(T next) { switch (state) { case SortedState.NoValues: state = SortedState.Undecided; break; case SortedState.Undecided: case SortedState.Ascending: case SortedState.Descending: int cmp = next.CompareTo(lastValue); switch (state) { case SortedState.Undecided: if (cmp > 0) { state = SortedState.Ascending; } else if (cmp < 0) { state = SortedState.Descending; } else { uniqueValues = false; } break; case SortedState.Ascending: if (cmp < 0) { state = SortedState.Mixture; } else if (cmp == 0) { // Not unique uniqueValues = false; } break; case SortedState.Descending: if (cmp > 0) { state = SortedState.Mixture; } else if (cmp == 0) { // Not unique uniqueValues = false; } break; } break; } lastValue = next; return this; } public SortedState State() { return state; } public bool? Unique() { return state == SortedState.Mixture ? (bool?)null : uniqueValues; } public override string ToString() { return string.Format( "{0} ({1})", State(), Unique().HasValue ? (Unique().Value ? "unique" : "not unique") : "unknown uniqueness"); } }; static void CheckIfSorted(IEnumerable values) where T : IComparable { Console.WriteLine( values.Aggregate( new AscOrDescHelper(), (last, next) => last.ProcessNextValue(next))); } static void Main() { CheckIfSorted(new string[]{ "amy", "kate", "sally" }); CheckIfSorted(new int[]{ 7, 5, 5 }); CheckIfSorted(new int[]{ 2, 3, 1 }); // Gives: // Ascending (unique) // Descending (not unique) // Mixture (unknown uniqueness) } 

我是C#初学者,所以欢迎建设性的建议;)

LINQ扩展。 MoreLinq图书馆的优秀候选人:

 public static bool IsOrdered(this IEnumerable source, IComparer comparer = null) { return source.IsOrdered(OrderByDirection.Ascending, comparer); } public static bool IsOrdered(this IEnumerable source, OrderByDirection direction, IComparer comparer = null) { if (source == null) { throw new ArgumentNullException(nameof(source)); } if (comparer == null) { comparer = Comparer.Default; } int d = direction == OrderByDirection.Ascending ? 1 : -1; Func compareFunc= (i1, i2) => d * comparer.Compare(i1, i2); return IsOrderedImpl(source, compareFunc); } public static bool IsOrdered(this IEnumerable source, Func 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(this IEnumerable source, Func 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)); }