[C#] IEnumerable에서 요소의 인덱스를 얻는 방법은 무엇입니까?

나는 이것을 썼다 :

public static class EnumerableExtensions
{
    public static int IndexOf<T>(this IEnumerable<T> obj, T value)
    {
        return obj
            .Select((a, i) => (a.Equals(value)) ? i : -1)
            .Max();
    }

    public static int IndexOf<T>(this IEnumerable<T> obj, T value
           , IEqualityComparer<T> comparer)
    {
        return obj
            .Select((a, i) => (comparer.Equals(a, value)) ? i : -1)
            .Max();
    }
}

그러나 이미 존재하는지 모르겠습니다.



답변

IEnumerable로 물건을 가져 오는 요점은 내용을 느리게 반복 할 수 있다는 것입니다. 따라서 실제로 인덱스 개념 이 없습니다 . 당신이하고있는 일은 실제로 IEnumerable에 많은 의미가 없습니다. 인덱스 별 액세스를 지원하는 것이 필요하면 실제 목록이나 컬렉션에 넣으십시오.


답변

나는 지혜에 의문을 제기하지만 아마도 :

source.TakeWhile(x => x != value).Count();

( 필요한 경우 EqualityComparer<T>.Default에뮬레이션을 사용하여 !=)-찾을 수 없으면 -1을 반환해야합니다 … 아마도 먼 길을 가십시오.

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;
}


답변

나는 이것을 다음과 같이 구현할 것이다 :

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;
    }
}


답변

내가 현재하고있는 방법은 이미 제안 된 것보다 약간 짧으며 내가 알 수있는 한 원하는 결과를 얻습니다.

 var index = haystack.ToList().IndexOf(needle);

약간 어수선하지만 작업을 수행하고 상당히 간결합니다.


답변

위치를 잡는 가장 좋은 방법은 FindIndex다음과 같습니다.List<>

int id = listMyObject.FindIndex(x => x.Id == 15); 

열거 자 또는 배열이있는 경우이 방법을 사용하십시오

int id = myEnumerator.ToList().FindIndex(x => x.Id == 15); 

또는

 int id = myArray.ToList().FindIndex(x => x.Id == 15); 


답변

가장 좋은 옵션은 다음과 같이 구현하는 것입니다.

public static int IndexOf<T>(this IEnumerable<T> enumerable, T element, IEqualityComparer<T> comparer = null)
{
    int i = 0;
    comparer = comparer ?? EqualityComparer<T>.Default;
    foreach (var currentElement in enumerable)
    {
        if (comparer.Equals(currentElement, element))
        {
            return i;
        }

        i++;
    }

    return -1;
}

또한 익명 개체를 만들지 않습니다


답변

게임에서 약간 늦었지만 알고 있습니다. 그러나 이것은 내가 최근에 한 일입니다. 그것은 당신과 약간 다르지만, 프로그래머가 평등 연산이 필요한 것을 지시 할 수 있습니다 (조건 자). 다른 유형을 처리 할 때 객체 유형에 관계없이 <T>평등 연산자에 내장 된 일반적인 방법을 가지고 있기 때문에 매우 유용합니다 .

또한 메모리 공간이 매우 작고 매우 빠르며 효율적입니다.

더 나쁜 것은 확장 목록에 추가하면됩니다.

어쨌든 … 여기 있습니다.

 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;
 }

잘하면 이것은 누군가를 돕는다.