C# 林克:拿的“对立面”是什么?

C# 林克:拿的“对立面”是什么?,c#,linq,C#,Linq,使用Linq;我怎么能做与Take相反的事情呢 即,不获取前n个元素,如 aCollection.Take(n) 我想得到除最后n个元素以外的所有元素。差不多 aCollection.Leave(n) 不要问为什么:- 编辑 我想我可以这样做aCollection.TakeWhilex,index=>index

使用Linq;我怎么能做与Take相反的事情呢

即,不获取前n个元素,如

aCollection.Take(n)
我想得到除最后n个元素以外的所有元素。差不多

aCollection.Leave(n)
不要问为什么:-

编辑

我想我可以这样做aCollection.TakeWhilex,index=>index
public static IEnumerable<TSource> Leave<TSource>(this IEnumerable<TSource> source, int n) 
{ 
  return source.TakeWhile((x, index) => index < source.Count() - n); 
}
但是在LINQtoSQL或NHibernateLINQ的情况下,如果生成的SQL能够处理它并生成类似于FORSQLServer/T-SQL的内容,那就更好了

选择TOPSELECT COUNT*-@n FROM ATable*FROM ATable或其他更聪明的SQL实现

我想没有比这更好的了吧?
但编辑实际上并不是问题的一部分。

我很确定没有内置的方法,但通过链接Reverse和Skip可以轻松完成:

编辑:正如注释中出现的一条有趣的信息一样,您可能会认为IEnumerable的扩展方法.Count很慢,因为它会遍历所有元素。但如果实际对象实现ICollection或ICollection,它将只使用.Count属性,该属性应为O1。因此,在这种情况下,性能不会受到影响


您可以看到IEnumerable.Count的源代码。

我不相信有内置函数用于此

aCollection.TakeaCollection.Count-n


应该是合适的;将集合中的项目总数减去n应跳过最后n个元素。

这将比使用双反转的解决方案更有效,因为它只创建一个列表,并且只枚举一次列表

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
遵循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();
}
目前,C定义了一个TakeLastn方法,该方法从字符串的末尾获取字符


请参见此处:

注意:这与跳过不同!哇,你们真快!看来Shedal和Jim Dagg的答案对我来说是最好的。我如何知道选择哪一个作为正确答案?吉姆更快,但谢达尔获得了选票。接受谢达尔的回答。Reverse在数据库上不起作用,因为数据库本质上需要一个限定符来对您想要排序的字段进行排序,当我在ORM上测试时,它有一个运行时错误。我在ORM上测试了Shedal的代码,他的代码运行得很好实际上,Shedal更快,在撰写本文时,他在29分钟前回答;吉姆·达格的成绩是27分钟ago@MichaelBuen:你说得对,谢达尔是第一个。我不知道我在想什么,你是说一个集合,伯爵?长度是数组的一个属性。也不需要在结尾处使用。当然,假设npublic 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
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();
}