Получить индекс элемента в списке, учитывая его свойство

В List<Person> MyList List<Person> может быть Person у которого для свойства Name установлено значение "ComTruise". Мне нужен индекс первого появления "ComTruise" в MyList, но не весь элемент Person.

Что я делаю сейчас:

string myName = ComTruise;
int thatIndex = MyList.SkipWhile(p => p.Name != myName).Count();

Если список очень большой, есть ли более оптимальный способ получить индекс?

Ответ 1

Как и ObservableCollection, вы можете попробовать это

int index = MyList.IndexOf(MyList.Where(p => p.Name == "ComTruise").FirstOrDefault());

Он вернет -1, если "ComTruise" не существует в вашей коллекции.

Как указано в комментариях, это выполняет два поиска. Вы можете оптимизировать его с помощью цикла for.

int index = -1;
for(int i = 0; i < MyList.Count; i++)
{
    //case insensitive search
    if(String.Equals(MyList[i].Name, "ComTruise", StringComparison.OrdinalIgnoreCase)) 
    {
        index = i;
        break;
    } 
}

Ответ 2

Вы могли бы использовать FindIndex

string myName = "ComTruise";
int myIndex = MyList.FindIndex(p => p.Name == myName);

Примечание. FindIndex возвращает -1, если в списке не найдено ни одного элемента, соответствующего условиям, определенным предоставленным предикатом.

Ответ 3

Возможно, имеет смысл написать простой метод расширения, который делает это:

public static int FindIndex<T>(
    this IEnumerable<T> collection, Func<T, bool> predicate)
{
    int i = 0;
    foreach (var item in collection)
    {
        if (predicate(item))
            return i;
        i++;
    }
    return -1;
}

Ответ 4

var p = MyList.Where(p => p.Name == myName).FirstOrDefault();
int thatIndex = -1;
if (p != null)
{
  thatIndex = MyList.IndexOf(p);
}

if (p != -1) ...