FindLast on IEnumerable
Asked Answered
E

5

7

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

Enharmonic answered 12/1, 2009 at 15:20 Comment(0)
E
10

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).

Extremism answered 12/1, 2009 at 15:41 Comment(1)
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.Eagre
S
5

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;
    }
}
Stuck answered 12/1, 2009 at 15:46 Comment(2)
The top bit, maybe - but I thought the 2.0 stuff might be useful, so I kept it separate.Stuck
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!Maybellmaybelle
B
1

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

List<MyClass> myList = new List<MyClass>(MyCol);
myList.FindLast....
Bromoform answered 12/1, 2009 at 15:30 Comment(0)
F
0

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

Ferrotype answered 12/1, 2009 at 15:29 Comment(0)
G
0

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.

Gaily answered 12/1, 2009 at 17:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.