有一些标准方法来计算符合某些条件的元素数量:
collection.Where(d=> d==something).Count();
我需要以下功能(伪鳕鱼):
collection.Where(d=> (d==something) && (d.Next == somethingElse)).Count();
编辑:d.Next - 是集合中d之后的下一个元素。
如何实现这一目标?
答案 0 :(得分:5)
假设你所拥有的是一个涉及源序列中连续元素的谓词,你可以这样做:
int numMatches = collection.Zip(collection.Skip(1), (prev, next) =>
prev == something && next == somethingElse)
.Count(match => match)
在应用过滤器之前,这会将序列叠加在序列的一个延迟版本上。
答案 1 :(得分:3)
var result = collection.Count(d =>
d == something &&
d.Next == somethingElse
);
如果d.Next
属性为d
或序列中的下一个元素,则编辑:
var result = collection.Zip(
collection.Skip(1),
(first, second) => first == something && second == somethingElse
).Count(i => i);
答案 2 :(得分:1)
您可以编写一个新的运算符(假设Linq-to-objects),使用枚举器明确地检查它。
<强>代码:强>
public static partial class Enumerable
{
public static IEnumerable<TSource> WhereNext<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate, TSource next)
{
if (source == null)
throw new ArgumentNullException("source");
if (predicate == null)
throw new ArgumentNullException("predicate");
return WhereNextImpl(source, predicate, next);
}
private static IEnumerable<TSource> WhereNextImpl<TSource>(IEnumerable<TSource> source, Func<TSource, bool> predicate, TSource next)
{
using (var enumerator = source.GetEnumerator())
{
TSource current;
TSource nextElement;
if (!enumerator.MoveNext())
yield break;
while (true)
{
current = enumerator.Current;
if (!enumerator.MoveNext())
yield break;
nextElement = enumerator.Current;
if (predicate(current) && EqualityComparer<TSource>.Default.Equals(next, nextElement))
yield return current;
}
}
}
}
警告:目前使用EqualityComparer<TSource>.Default
进行比较。应该完成另一个使用自定义比较器的实现。
答案 3 :(得分:1)
如果收集是stirng的列表,你可以尝试像
这样的东西var selectC = from c in collection
let nextC = collection.IndexOf(c) == collection.Count - 1 ? null : collection[collection.IndexOf(c) + 1]
where string.IsNullOrEmpty(c) && string.IsNullOrEmpty(nextC)
select c;
涉及let的查询很难转化为方法链但我从Resharper的自动转换得到了这个
var selectC =
collection.Select(
c =>
new {c, nextC = collection.IndexOf(c) == collection.Count - 1 ? null : collection[collection.IndexOf(c) + 1]}).
Where(@t => string.IsNullOrEmpty(@t.c) && string.IsNullOrEmpty(@t.nextC)).Select(@t => @t.c);
答案 4 :(得分:1)
您可以使用Aggregate Method创建自定义总和:
var result = collection.Aggregate(
Tuple.Create(false, 0),
(s, x) => Tuple.Create(x == something,
s.Item1 + (s.Item0 && (x == somethingElse) ? 1 : 0)),
s => s.Item1);
它的工作原理如下:
Item Accumulator --------------- --------------- (false, 0) foo (false, 0) something (true, 0) bar (false, 0) something (true, 0) somethingElse (false, 1) somethingElse (false, 1) baz (false, 1) --------------- Result: 1