Reputation: 102
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.
Upvotes: 3
Views: 212
Reputation: 14700
This option takes advantage of the Where
overload that takes an index, and use it to skip the next-to-last index.
var count = items_split.Count();
items_split.Where((item, index) => index != count -2)
Note, though, that this will call Count
to get the total count, which will result in an iteration of the IEnumerable, and then a second iteration with Where
. You might want to get a concrete, materialized collection first.
This might seem to defeat the point of using an IEnumerable
in the first place, but remember, if your logic asks for the next-to-last, it means that you have to get to the end of the collection to know that it's the next to last.
Upvotes: -2
Reputation: 186698
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);
Upvotes: 4
Reputation: 1594
You can try another approach with List.RemoveAt(int)
where int
is index
you want to remove.
items_split.RemoveAt(items_split.Count - 2);
Upvotes: 1
Reputation: 45947
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));
Upvotes: 3