如何使用 LINQ 选择在一列中带条件
本文关键字:一列 条件 LINQ 何使用 选择 | 更新日期: 2023-09-27 18:31:48
像这样的数据表...
Date Count
20160101 100
20160102 103
20160103 108
20160104 102
20160105 104
20160106 106
20160107 108
我要select if => someday.Count > someday[-3].Count
结果 = 下面的 3 行:
20160104,因为102>100
20160105,因为104>103
20160107,因为108>102
请告诉我如何使用 LINQ?
多谢
一种方法是这样做。
int index = 0;
var a = from i in someday
let indexNow = index++
where indexNow >= 3
let j = someday[indexNow - 3]
where i.Count > j.Count
select i;
您创建临时变量 j 以在三步之前获取元素,然后将其与当前元素进行比较以检查它是否满足特定条件。如果是,则选择它
按如下方式使用索引Where
-重载:
var result = myDates.Where((x, index) => index >= 3 && x > myDates.ElementAt(x - 3).Count);
这会从您的集合中选择所有那些元素,这些元素的计数比三天前的元素更多。
Where
将Func<TSource, int, bool> predicate
作为输入的重载。此委托的第二个输入是当前元素的索引。因此,这意味着您的 lambda 表达式必须接受两个输入,第一个输入是元素的类型,另一个是Int32
。 Where
方法将自动计算当前元素的索引。
var result = myColl.Where((x, index) => index >= 3 && x.Count > myColl.ElementAt(index - 3).Count);
然后,您可以使用所需的方法,如Select()
,ToList()
等。
PS:我假设对象的名称是myColl
。
此外:
我总是喜欢告诉开发人员有关http://referencesource.microsoft.com/
的信息。您可以轻松找到所有方法的实现以及有关 C# 源代码的所有内容。如果您有兴趣,这里是Where
方法重载的源代码。
public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source, Func<TSource, int, bool> predicate) {
if (source == null) throw Error.ArgumentNull("source");
if (predicate == null) throw Error.ArgumentNull("predicate");
return WhereIterator<TSource>(source, predicate);
}
如您所见,它将返回WhereIterator
,它将自动计算当前项目的索引并将其发送到您的方法:
static IEnumerable<TSource> WhereIterator<TSource>(IEnumerable<TSource> source, Func<TSource, int, bool> predicate) {
int index = -1;
foreach (TSource element in source) {
checked { index++; }
if (predicate(element, index)) yield return element;
}
}
虽然其他答案中描述的索引技术可以工作,但如果源序列不是基于列表的,它们将效率低下,在这种情况下ElementAt
将导致 O(N^2) 时间复杂度运算。
对于仅 O(N) 时间复杂度(如果源序列本身不包含繁重的操作)的一种可能更好的方法是使用 Skip 和 Zip 的组合,如下所示
var result = myDates
.Skip(3)
.Zip(myDates, (current, compare) => current.Count > compare.Count ? current : null)
.Where(item => item != null);