从IEnumerable中的倒数第二个项目跳过

时间:2018-07-09 11:11:42

标签: c#

我有一个IEnumerable不是 List),如下所示:

A,B,C,D,E

使用以下命令,我将跳过最后一项(E):

items_split.Take(items_split.Count() - 1);  //output : A,B,C,D

使用以下命令,我将跳过第一项(A):

items_split.Skip(1); //output : B,C,D,E

如何跳过列表中的倒数第二个项目? (所需结果为A,B,C,E

注意:不是最后一个,而是紧接在最后一个之前。

4 个答案:

答案 0 :(得分:4)

让我们利用items_splitList<T>的事实-我们可以使用Count

var result = items_split
  .Where((value, index) => index != items_split.Count() - 2);

一般情况下(当items_splitIEnumerable<T>时,只有Count可能过于昂贵甚至误解,例如,如果您查询的文件可能是Count之后>更改):

public static IEnumerable<T> ExcludePenultimate<T>(IEnumerable<T> source) {
  if (null == source)
    throw new ArgumentNullException(nameof(source));

  Queue<T> queue = new Queue<T>();

  foreach (var item in source) {
    queue.Enqueue(item);

    if (queue.Count > 2) 
      yield return queue.Dequeue();
  }

  if (queue.Count > 2)
    yield return queue.Dequeue();

  if (queue.Count == 2)
    queue.Dequeue();

  yield return queue.Dequeue();
}

然后

var result = ExcludePenultimate(items_split);

答案 1 :(得分:3)

使用Skip()Take()的另一种方法

List<char> items = new List<char>() { 'A', 'B', 'C', 'D', 'E' };
var result =  items.Take(items.Count() - 2).Concat(items.Skip(items.Count() - 1));

答案 2 :(得分:1)

您可以尝试使用List.RemoveAt(int)的另一种方法,其中int是要删除的index

items_split.RemoveAt(items_split.Count - 2);

答案 3 :(得分:-2)

此选项利用了Where重载的优势,该重载获取索引,并使用它跳过倒数第二个索引。

var count = items_split.Count();
items_split.Where((item, index) => index != count -2)

但是请注意,这将调用Count以获取总计数,这将导致IEnumerable的迭代,然后使用Where进行第二迭代。您可能想先获得一个具体的,物化的集合。

这似乎可以克服首先使用IEnumerable的问题,但请记住,如果您的逻辑要求倒数第二,则意味着您必须到达结束知道是倒数第二个。