林克:Take的“反面”
本文关键字:反面 Take 林克 | 更新日期: 2023-09-27 18:31:43
Using Linq;我怎样才能做到Take的"相反"?
即而不是获取前 n 个元素,例如
aCollection.Take(n)
我想得到除最后 n 个元素之外的所有元素。类似的东西
aCollection.Leave(n)
(不要问为什么:-)
编辑
我想我可以这样做 aCollection.TakeWhile((x, index) => index < aCollection.Count - n)
或者以扩展的形式
public static IEnumerable<TSource> Leave<TSource>(this IEnumerable<TSource> source, int n)
{
return source.TakeWhile((x, index) => index < source.Count() - n);
}
但是在Linq to SQL或NHibernate Linq的情况下,如果生成的SQL处理它并生成类似的东西(对于SQL Server/T-SQL)会很好。
SELECT TOP(SELECT COUNT(*) -@n FROM ATable) * FROM ATable
或者其他一些更聪明的SQL实现。
我想没有比这更好的了?(但编辑实际上不是问题的一部分。
aCollection.Take(aCollection.Count() - n);
编辑:就像评论中出现的一条有趣的信息 - 你可能会认为IEnumerable
的扩展方法.Count()
很慢,因为它会遍历所有元素。但是如果实际对象实现ICollection
或ICollection<T>
,它将只使用应该是O(1)的.Count
属性。因此,在这种情况下,性能不会受到影响。
您可以在 TypeDescriptor.net 看到IEnumerable.Count()
的源代码。
我很确定没有内置的方法,但这可以通过链接Reverse
和Skip
轻松完成:
aCollection.Reverse().Skip(n).Reverse()
我不相信有内置函数。
aCollection.Take(aCollection.Count - n)
应该是合适的;将集合中的项目总数减去 n 应该跳过最后 n 个元素。
按照IEnumerable
哲学,对于未实现ICollection
的情况进行一次枚举,您可以使用以下扩展方法:
public static IEnumerable<T> Leave<T>(this ICollection<T> src, int drop) => src.Take(src.Count - drop);
public static IEnumerable<T> Leave<T>(this IEnumerable<T> src, int drop) {
IEnumerable<T> IEnumHelper() {
using (var esrc = src.GetEnumerator()) {
var buf = new Queue<T>();
while (drop-- > 0)
if (esrc.MoveNext())
buf.Enqueue(esrc.Current);
else
break;
while (esrc.MoveNext()) {
buf.Enqueue(esrc.Current);
yield return buf.Dequeue();
}
}
}
return (src is ICollection<T> csrc) ? csrc.Leave(drop) : IEnumHelper();
}
这将比具有双重反向的解决方案更有效,因为它只创建一个列表,并且只枚举该列表一次。
public static class Extensions
{
static IEnumerable<T> Leave<T>(this IEnumerable<T> items, int numToSkip)
{
var list = items.ToList();
// Assert numToSkip <= list count.
list.RemoveRange(list.Count - numToSkip, numToSkip);
return List
}
}
string alphabet = "abcdefghijklmnopqrstuvwxyz";
var chars = alphabet.Leave(10); // abcdefghijklmnop
目前,C# 定义了 TakeLast(n)
方法,该方法从字符串末尾获取字符。
请参阅此处: https://msdn.microsoft.com/en-us/library/hh212114(v=vs.103).aspx