user70192
user70192

Reputation: 14204

C# - Get Second to Last Item in a List

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

Answers (5)

مهدی
مهدی

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

Dekel
Dekel

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

Valentin
Valentin

Reputation: 5488

You can use ElementAtOrDefault

items.ElementAtOrDefault(items.Count - 2) 

Or Take and LastOrDefault

items.Take(items.Length - 1).LastOrDefault();

Upvotes: 9

Ren&#233; Vogt
Ren&#233; Vogt

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

Xiaoy312
Xiaoy312

Reputation: 14477

Try this :

items.AsEnumerable().Reverse().Skip(1).FirstOrDefault();

Upvotes: 25

Related Questions