假设我有一个数字列表,我想知道数字在列表中的哪个位置开始减少,没有特定的顺序,一个例子是理想的!
1,
2,
2,
3,
3,
4,
4,
5,
5,
4, <= this should be my output
4,
3,
3,
2,
2,
1,
谢谢
您可以创建自己的扩展方法IEnumerable<TSource>
public static class MyEnumerable
{
public static IEnumerable<TSource> Descending<TSource>(this IEnumerable<TSource> source)
where TSource : IComparable<TSource>
{
using (var e = source.GetEnumerator())
{
TSource previous;
if (e.MoveNext())
{
previous = e.Current;
while (e.MoveNext())
{
if (previous.CompareTo(e.Current) > 0)
yield return e.Current;
previous = e.Current;
}
}
}
}
}
用法
var input = new List<int>() { 1, 2, 3, 2, 4, 5, 6, 7, 8, 9 };
var firstDescending = input.Descending().First();
不是 Linq,而是 C# 方式:
public int FirstDecreasingIndex(IList<int> myList)
{
for (int i = 0; i < myList.Count - 1; i++)
{
if (myList[i] > myList[i + 1])
return i+1;
}
return -1; //Or some other value
}
对于此输入:
{ 1,2,3,2,4,5,6,7,8,9 }
该函数将返回3
,因为它是列表第一次开始减少的第一个索引。
对于真正实用的方法:
List<int> numbers = ...;
var firstDecreasingValue =
numbers.Skip(1).Zip(numbers, (number, previous) => new { number, previous })
.Where(x => x.number.CompareTo(x.previous) < 0)
.Select(x => x.number)
.First();
不完全是linq,但我认为足够接近
var list = new List<int> { 1, 2, 3, 4, 5, 4, 3, 2, 1 };
var index = Enumerable.Range(0, list.Count).First(i => i > 0 && list[i] < list[i - 1]);
这是一个使用Enumerable.Aggregate
and Tuple
:s 的“oneliner”:
var numbers = new[] { 1, 2, 2, 3, 3, 4, 4, 5, 5, 4, 4, 3, 3, 2, 2, 1 };
var idx = numbers.Aggregate(Tuple.Create(true, 0, 0), (tuple, x) =>
tuple.Item1
? tuple.Item3 <= x
? Tuple.Create(true, tuple.Item2 + 1, x)
: Tuple.Create(false, tuple.Item2, x)
: tuple)
.Item2;
聚合元组存储三个值:
聚合完成后,Item2
从元组中选择值,其中存储了第一个减少的索引。
上述代码的输出将是9
第一个减小值的基零索引。如果您改为Item3
从聚合元组返回,您将获得第一个减少的值(如果序列完全不减少,则获得最后一个值)。