views:

524

answers:

5

I would like to call FindLast on a collection which implements IEnumarable, but FindLast is only available for List. What is the best solution?

A: 

Use the extension method Last() which is located in the namespace System.Linq.

davcar
That doesn't apply the predicate...
Marc Gravell
+1  A: 

you can add you collection to a new List by passing it to List<> constructor.

List<MyClass> myList = new List<MyClass>(MyCol);
myList.FindLast....
pablito
+5  A: 

The equivalent to:

var last = list.FindLast(predicate);

is

var last = sequence.Where(predicate).LastOrDefault();

(The latter will have to check all items in the sequence, however...)

Effectively the "Where()" is the Find part, and the "Last()" is the Last part of "FindLast" respectively. Similarly, FindFirst(predicate) would be map to sequence.Where(predicate).FirstOrDefault() and FindAll(predicate) would be sequence.Where(predicate).

Jon Skeet
Note also FirstOrDefault(predicate), which saves a few keys ;-p
Marc Gravell
Yup, hadn't seen that. Doh!
Jon Skeet
Depending on the comparison method, length of list and frequency of matches it might be more CPU efficient to:sequence.Reverse.Where(predicate).FirstOrDefault();Not very memory efficient however.
mancaus
+3  A: 

How about with LINQ-to-Objects:

var item = data.LastOrDefault(x=>x.Whatever == "abc"); // etc

If you only have C# 2, you can use a utility method instead:

using System;
using System.Collections.Generic;
static class Program {
    static void Main() {
        int[] data = { 1, 2, 3, 4, 5, 6 };

        int lastOdd = SequenceUtil.Last<int>(
            data, delegate(int i) { return (i % 2) == 1; });
    }    
}
static class SequenceUtil {
    public static T Last<T>(IEnumerable<T> data, Predicate<T> predicate) {
        T last = default(T);
        foreach (T item in data) {
            if (predicate(item)) last = item;
        }
        return last;
    }
}
Marc Gravell
can we not just edit that into skeet's answer?
Ruben Bartelink
Forgot a smiley :D
Ruben Bartelink
The top bit, maybe - but I thought the 2.0 stuff might be useful, so I kept it separate.
Marc Gravell
Ah, only saw v1!Handn't even considered that one would go and invest the time to expand on it as you did...BTW for all these Util type things, PowerCollections used to be my hammer back when I was constrained to 2.0 - algorithms.cs is a great read. Bet it's Last() has an opt for Collection!
Ruben Bartelink
A: 

Your question is invalid because a collection has no last element. A more specialized collection that does have a complete ordering is a list. A more specialized collection that does not have an ordering is a dictionary.