71

I have a List in c# in which i am adding list fields.Now while adding i have to check condition,if the condition satisfies then i need to remove the last row added from the list. Here is my sample code..

    List<> rows = new List<>();
    foreach (User user in users)
    {
        try
        {
            Row row = new Row();
            row.cell = new string[11];
            row.cell[1] = user."";
            row.cell[0] = user."";
            row.cell[2] = user."";         

            rows.Add(row);

            if (row.cell[0].Equals("Something"))
            {

                //here i have to write code to remove last row from the list
                //row means all the last three fields

            }

        }

So my question is how to remove last row from list in c#. Please help me.

Dmitry
  • 13,797
  • 6
  • 32
  • 48
Pranav
  • 751
  • 1
  • 8
  • 12
  • 4
    Is `List<>` and `user.""` valid C#? – Tim Schmelter Apr 23 '14 at 13:18
  • 7
    What is the point of adding and removing the next thing? Check the condition first and if not met then add the row or else don't add it. – Marius Bancila Apr 23 '14 at 13:19
  • Removing LAST ADDED item is not possible in List class if you're not storing the input index externally somewhere. I suppose you meant to remove just last item, but then the whole example you provided is just pointless. – Tarec Apr 23 '14 at 13:26

6 Answers6

114

I think the most efficient way to do this is this is using RemoveAt:

rows.RemoveAt(rows.Count - 1)
Patrick Hofman
  • 153,850
  • 22
  • 249
  • 325
90

The direct answer to this question is:

if(rows.Any()) //prevent IndexOutOfRangeException for empty list
{
    rows.RemoveAt(rows.Count - 1);
}

However... in the specific case of this question, it makes more sense not to add the row in the first place:

Row row = new Row();
//...      

if (!row.cell[0].Equals("Something"))
{
    rows.Add(row);
}

TBH, I'd go a step further by testing "Something" against user."", and not even instantiating a Row unless the condition is satisfied, but seeing as user."" won't compile, I'll leave that as an exercise for the reader.

spender
  • 117,338
  • 33
  • 229
  • 351
  • 1
    There are cases that you may want to add and then remove the item you just added to the list. For example, if there are a lot of if-elseif conditions to check due to different business logics. In this case, you can add the row first before the if-elseif conditions. If after you validate all the conditions and none of them are satisfied, then remove this row from the list. You could put the rows.Add() into each condition, but that means if you have 10 IF statements, then you have to add rows.Add() to each 10 IF statements. – Dongminator Apr 20 '17 at 18:17
  • It might make more sense...but it doesn't answer the question. – DrMcCleod Jun 12 '18 at 13:05
  • 3
    @DrMcCleod Given this question's search-engine popularity, I've made an edit for those coming for a quick solution. – spender Jun 12 '18 at 15:50
  • 3
    I'm trying to use `rows.RemoveAt(^1)` and it doesn't compile: `Argument 1: cannot convert from 'System.Index' to 'int'` I don't think the `Index` type works for `RemoveAt()` method. – Carl Walsh Nov 19 '21 at 22:16
14
rows.RemoveAt(rows.Count - 1);
Patrick Hofman
  • 153,850
  • 22
  • 249
  • 325
Pradip Daunde
  • 381
  • 2
  • 5
9

You can use List<T>.RemoveAt method:

rows.RemoveAt(rows.Count -1);
Selman Genç
  • 100,147
  • 13
  • 119
  • 184
3

if you need to do it more often , you can even create your own method for pop the last element; something like this:

public void pop(List<string> myList) {
    myList.RemoveAt(myList.Count - 1);
}

or even instead of void you can return the value like:

public string pop (List<string> myList) {
    // first assign the  last value to a seperate string 
    string extractedString = myList(myList.Count - 1);
    // then remove it from list
    myList.RemoveAt(myList.Count - 1);
    // then return the value 
    return extractedString;
}

just notice that the second method's return type is not void , it is string b/c we want that function to return us a string ...

amdev
  • 6,703
  • 6
  • 42
  • 64
-3

I would rather use Last() from LINQ to do it.

rows = rows.Remove(rows.Last());

or

rows = rows.Remove(rows.LastOrDefault());
Lars
  • 9,976
  • 4
  • 34
  • 40
Liakat Hossain
  • 1,288
  • 1
  • 13
  • 24
  • 12
    Do **not** use it, when you have the index (e.g. `Count - 1` for last item) and use `RemoveAt`. Your solution comes along with decreased perfomance and perhaps bad behaviour: `Remove(T item)` uses its EqualityComparer (defaulted or specified by you) and searches in ascended index order for the first occurence of passed item which could be `rows.Last()`. When your list contains a duplication of `rows.Last()`, not the the last but the first occurence may be removed **if** the `EqualityComparer` does not only check for ReferenceEquals which is only default for `EqualityComparer.Default`. – Teneko Jan 21 '21 at 14:38
  • This has a huge performance penalty! – Jonan Gueorguiev Jun 28 '23 at 12:57