Reputation: 14204
I have some code written in C#. In this code, I have a List<KeyValuePair<int, string>> items
. I am trying to get the second-to-last item in the list. I'm having problems doing it though.
Originally, my collection was just a Dictionary<int, string>
. At that point, I was using:
var nextToLast = items.Reverse().Skip(1).FirstOrDefault();
That worked. However, since items
is now a List<KeyValuePair<int, string>>
, the Reverse
method returns a void
. So, I can't do the skip.
Anyone know of an elegant way for me to get the second-to-last item from a List<KeyValuePair<int, string>>
in C#?
I know I can use a loop. I just figured there had to be a better way.
Upvotes: 23
Views: 42615
Reputation: 442
public IList<string> newList = new List<string>();
public void OnGet()
{
var list = new List<string> { "one", "two", "three", "four" };
list.RemoveAt(0);
while (list.Count != 0)
{
var index = list.Next(0, list.Count);
newlist.Add(list[index]);
list.RemoveAt(index);
}
}
<tr>
<td>
@Model.newList[0]
<td>
<br />
<td>
@Model.newList[1]
<td>
<br />
<td>
@Model.newList[2]
<td>
<br />
</tr>
Upvotes: 1
Reputation: 62556
Starting with C# 8.0 you can use the ^
operator, which gives you access to the index from the end[1].
So you can just do:
var item = items[^2];
More examples:
int[] xs = new[] { 0, 10, 20, 30, 40 };
int last = xs[^1];
Console.WriteLine(last); // output: 40
var lines = new List<string> { "one", "two", "three", "four" };
string prelast = lines[^2];
Console.WriteLine(prelast); // output: three
string word = "Twenty";
Index toFirst = ^word.Length;
char first = word[toFirst];
Console.WriteLine(first); // output: T
Upvotes: 38
Reputation: 5488
You can use ElementAtOrDefault
items.ElementAtOrDefault(items.Count - 2)
Or Take
and LastOrDefault
items.Take(items.Length - 1).LastOrDefault();
Upvotes: 9
Reputation: 43876
You have a List<>
, so why not use its Count
and indexer properties:
var item = items[items.Count-2];
Make sure that there are at least two items in the list though.
Upvotes: 45
Reputation: 14477
Try this :
items.AsEnumerable().Reverse().Skip(1).FirstOrDefault();
Upvotes: 25