Получение индекса повторяющихся элементов в списке в С#

Я ищу способ получить индекс всех элементов в списке из поиска по ключевым словам в списке. Так, например, в моем списке есть:

Hello World
Programming Rocks
Hello
Hello World
I love C#
Hello

Теперь из этого списка строк я хочу получить все индексы элементов, которые говорят Hello World. Я пробовал следующее, но он возвращает только первый найденный индекс, который имеет мои критерии поиска:

    for (int i = 0; i< searchInList.Count; i++)
        foundHelloWorld[i] = searchInList.IndexOf("Hello World");

Кто-нибудь знает, как это сделать?

Спасибо

Ответ 1

searchInList.Select((value, index) => new {value, index})
    .Where(a => string.Equals(a.value, "Hello World"))
    .Select(a => a.index)

Если вы пытаетесь найти больше, чем просто "Hello World", вы можете сделать

searchInList.Select((value, index) => new {value, index})
    .Where(a => stringsToSearchFor.Any(s => string.Equals(a.value, s)))
    .Select(a => a.index)

Ответ 2

Поскольку вы знаете, что ищете ВСЕ записи, и поэтому вы должны пройти весь список в любом случае, вы получите большую удобочитаемость с помощью IndexOf, просто изучив каждый элемент самостоятельно:

var i=0;
foreach(var value in searchInList)
{
   if(value == "Hello World")
      foundHelloWorld.Add(i); //foundHelloWorld must be an IList

   i++;
}

Вы также можете использовать перегрузку метода Linq Select, который включает индекс элемента в исходной коллекции; это должно быть хорошо читаемым (и, следовательно, поддерживаемым) для опытных программистов Linq:

foundHelloWorld = searchInList
                     .Select((v,i)=>new {Index = i, Value = v})
                     .Where(x=>x.Value == "Hello World")
                     .Select(x=>x.Index)
                     .ToList();

Вышеприведенный код берет список и преобразует строку в простой анонимный тип, включающий каждое место в исходном списке. Затем он фильтрует до только совпадающих элементов, а затем проецирует индекс (который не изменился при фильтрации) в новый объект List. Тем не менее, все это преобразование заставит это решение работать медленнее, потому что этот оператор будет пересекать весь список несколько раз.

Ответ 3

Немного уродливый, но будет работать:

    var searchInList = new List<string>();

//Populate your list

    string stringToLookUp= "Hello world";
    var foundHelloWorldIndexes = new List<int>();

    for (int i = 0; i < searchInList.Count; i++)
        if (searchInList[i].Equals(stringToLookUp))
            foundHelloWorldIndexes.Add(i);

Ответ 4

Метод FindAll для списков здесь. Метод расширения списка Где здесь.

Оба из них будут делать практически то, что вы хотите, и они довольно просты в использовании. Есть много примеров каждого в Интернете, но если вам нужна помощь, просто сообщите мне.