在IEnumerable上查找最后一个元素

7

我想在实现了IEnumerable接口的集合上调用FindLast方法,但是FindLast只适用于List。有什么最好的解决方案吗?

5个回答

10

相当于:

var last = list.FindLast(predicate);

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

然而,后者将不得不检查序列中的所有项...

实际上,“Where()”是“Find”的部分,而“Last()”是“FindLast”的部分。同样地,FindFirst(predicate)将映射到sequence.Where(predicate).FirstOrDefault(),而FindAll(predicate)将是sequence.Where(predicate)


根据比较方法、列表长度和匹配频率,使用以下代码可能更加CPU高效: sequence.Reverse.Where(predicate).FirstOrDefault();但是这种方法并不太内存高效。 - mancaus

5
使用LINQ-to-Objects呢?
var item = data.LastOrDefault(x=>x.Whatever == "abc"); // etc

如果你只有C# 2,你可以使用一个实用方法代替:
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;
    }
}

最高位可能是 - 但我认为2.0的东西可能会有用,所以我将其保持独立。 - Marc Gravell
啊,只看到 v1 了!甚至没有考虑过有人会像你这样投入时间来扩展它...顺便说一下,对于所有这些 Util 类型的东西,当我被限制在 2.0 版本时,PowerCollections 曾经是我的利器 - algorithms.cs 是一个很棒的阅读材料。打赌它的 Last() 方法有一个针对 Collection 的优化! - Ruben Bartelink

1

你可以通过将集合传递给List<>构造函数来将其添加到新列表中。

List<MyClass> myList = new List<MyClass>(MyCol);
myList.FindLast....

0
使用位于命名空间 System.Linq 中的扩展方法 Last()。

0

您的问题无效,因为集合没有最后一个元素。一个更专门化具有完全排序的集合是列表。一个更专门化不具有排序的集合是字典。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接