[LINQ].NET/C#程序开发在IEnumerable<T>的集合中查找某个元素的索引位置?

.NET 作者: Rector 405阅读 0评论 0收藏 收藏本文

郑重申明:本文未经许可,禁止任何形式转载

问题描述

.NET/C#程序开发中,比如当前有一个IEnumerable<T>的集合(注意:不是List<T>),现需要在这个IEnumerable<T>中查找某个指定元素的索引位置,应该如何实现呢?

方案一

使用EqualityComparer<T>.Default作为比较器来实现查询IEnumerable<T>的某个元素索引位置的需求,创建一个静态扩展方法 如下:

public static int IndexOf<T>(this IEnumerable<T> source, T value)
{
    int index = 0;
    var comparer = EqualityComparer<T>.Default; // or pass in as a parameter
    foreach (T item in source)
    {
        if (comparer.Equals(item, value)) return index;
        index++;
    }
    return -1;
}

方案二

另一种基于EqualityComparer<T>.Default的静态扩展方法实现,如下:

public static class EnumerableExtensions
{
    public static int IndexOf<T>(this IEnumerable<T> obj, T value)
    {
        return obj.IndexOf(value, null);
    }

    public static int IndexOf<T>(this IEnumerable<T> obj, T value, IEqualityComparer<T> comparer)
    {
        comparer = comparer ?? EqualityComparer<T>.Default;
        var found = obj
            .Select((a, i) => new { a, i })
            .FirstOrDefault(x => comparer.Equals(x.a, value));
        return found == null ? -1 : found.i;
    }
}

方案三

public static int IndexOf<T>(this IEnumerable<T> source, Func<T, bool> predicate)
 {
     int retval = -1;
     var enumerator = source.GetEnumerator();

     while (enumerator.MoveNext())
     {
         retval += 1;
         if (predicate(enumerator.Current))
         {
             IDisposable disposable = enumerator as System.IDisposable;
             if (disposable != null) disposable.Dispose();
             return retval;
         }
     }
     IDisposable disposable = enumerator as System.IDisposable;
     if (disposable != null) disposable.Dispose();
     return -1;
 }

方案四

public static int IndexOf<T>(this IEnumerable<T> list, T item)
{
    return list.Select((x, index) => EqualityComparer<T>.Default.Equals(item, x)
                                     ? index
                                     : -1)
               .FirstOr(x => x != -1, -1);
}

或者查找某个元素出现的第一次的索引位置,如下:

public static T FirstOr<T>(this IEnumerable<T> source, T alternate)
{
    return source.DefaultIfEmpty(alternate)
                 .First();
}

public static T FirstOr<T>(this IEnumerable<T> source, Func<T, bool> predicate, T alternate)
{
    return source.Where(predicate)
                 .FirstOr(alternate);
}

阅读了该文章的人还浏览了...

本文永久链接码友网 » [LINQ].NET/C#程序开发在IEnumerable<T>的集合中查找某个元素的索引位置?

发布于: 2018-03-19 15:14:03
分享扩散:

文章评论

获取验证码