Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Skip from penultimate item in the IEnumerable

Tags:

c#

I have a IEnumerable (not List) like the following list :

A,B,C,D,E

With the command below, I will skip the last item (E) :

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

And with the command below, I will skip the first item (A) :

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

how can i skip the penultimate item in the list? (desired result is A,B,C,E)

Note : not the last, but immediately before the last.

like image 551
Reza Hatami Avatar asked Oct 18 '25 10:10

Reza Hatami


2 Answers

Let's exploit the fact that items_split is a List<T> - we can use Count:

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

In general case (when items_split is IEnumerable<T> only Count can be too expencive or even misleasing e.g. if you query a file which can be changed after 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();
}

and then

var result = ExcludePenultimate(items_split);
like image 64
Dmitry Bychenko Avatar answered Oct 21 '25 01:10

Dmitry Bychenko


Another approach with Skip() and 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));
like image 32
fubo Avatar answered Oct 21 '25 00:10

fubo