Is it possible to use LINQ to check if all numbers in a list are increasing monotonically?

前端 未结 8 2602
旧巷少年郎
旧巷少年郎 2021-02-20 17:14

I\'m interested if there is a way, in LINQ, to check if all numbers in a list are increasing monotonically?

Example

List l         


        
相关标签:
8条回答
  • 2021-02-20 17:55

    Here is a one-liner that will work:

    var isIncreasing = list.OrderBy(x => x).SequenceEqual(list);
    

    Or if you're going for performance, here is a one-liner that will only traverse the list once, and quits as soon as it reaches an element out of sequence:

    var isIncreasing = !list.SkipWhile((x, i) => i == 0 || list[i - 1] <= x).Any();
    
    0 讨论(0)
  • 2021-02-20 17:55

    Use a loop! It's short, fast and readable. With the exception of Servy's answer, most the solutions in this thread are unnecessarily slow (sorting takes 'n log n' time) .

    // Test whether a sequence is strictly increasing.
    public bool IsIncreasing(IEnumerable<double> list)
    {
        bool initial = true;
        double last = Double.MinValue;
        foreach(var x in list)
        {
            if (!initial && x <= last)
                return false;
    
            initial = false;
            last = x;
        }
    
        return true;
    }
    

    Examples

    1. IsIncreasing(new List<double>{1,2,3}) returns True
    2. IsIncreasing(new List<double>{1,3,2}) returns False
    0 讨论(0)
  • 2021-02-20 18:01
    public static class EnumerableExtensions
    {
        private static bool CompareAdjacentElements<TSource>(this IEnumerable<TSource> source,
            Func<TSource, TSource, bool> comparison)
        {
            using (var iterator = source.GetEnumerator())
            {
                if (!iterator.MoveNext())
                    throw new ArgumentException("The input sequence is empty", "source");
                var previous = iterator.Current;
                while (iterator.MoveNext())
                {
                    var next = iterator.Current;
                    if (comparison(previous, next)) return false;
                    previous = next;
                }
                return true;
            }
        }
    
        public static bool IsSorted<TSource>(this IEnumerable<TSource> source)
            where TSource : IComparable<TSource>
        {
            return CompareAdjacentElements(source, (previous, next) => previous.CompareTo(next) > 0);
        }
    
        public static bool IsSorted<TSource>(this IEnumerable<TSource> source, Comparison<TSource> comparison)
        {
            return CompareAdjacentElements(source, (previous, next) => comparison(previous, next) > 0);
        }
    
        public static bool IsStrictSorted<TSource>(this IEnumerable<TSource> source)
            where TSource : IComparable<TSource>
        {
            return CompareAdjacentElements(source, (previous, next) => previous.CompareTo(next) >= 0);
        }
    
        public static bool IsStrictSorted<TSource>(this IEnumerable<TSource> source, Comparison<TSource> comparison)
        {
            return CompareAdjacentElements(source, (previous, next) => comparison(previous, next) >= 0);
        }
    }
    
    0 讨论(0)
  • 2021-02-20 18:05

    By using an Enumerable.Aggregate method:

    list1.Aggregate((a, i) => a > i ? double.MaxValue : i) != double.MaxValue;
    
    0 讨论(0)
  • 2021-02-20 18:12
    public static bool IsIncreasingMontonically<T>(List<T> list) 
        where T : IComparable
    {
        return list.Zip(list.Skip(1), (a, b) => a.CompareTo(b) <= 0)
            .All(b => b);
    }
    

    Note that this iterates the sequence twice. For a List, that's not a problem at all, for an IEnumerable or IQueryable, that could be bad, so be careful before you just change List<T> to IEnumerable<T>.

    0 讨论(0)
  • 2021-02-20 18:17

    Would you not order the list using OrderBy() and compare them against the original? If they are the same then it will give your your answer pseudo speaking:

    var increasing = orignalList.OrderBy(m=>m.value1).ToList();
    var decreasing = orignalList.OrderByDescending(m=>m.value1).ToList();
    
    var mono = (originalList == increasing || originalList == decreasing)
    
    0 讨论(0)
提交回复
热议问题