Невозможно отобразить правильные индексы выбранного пользователем элемента списка - PullRequest
0 голосов
/ 11 июля 2020

У меня есть стандартный список строк: List<string> Моя цель - заставить программу проходить по списку, собирать индексы всех строк, а затем отображать соответствующий индекс выбранной пользователем строки или идентификаторы, если он повторяется. У меня также есть оператор if, чтобы поймать, если пользовательский ввод не соответствует записи из списка. Я использую .ToLower (), чтобы попытаться отформатировать ввод пользователя.

Это то, что у меня есть до сих пор, и оно ведет себя очень неожиданно: возвращает:

Вывод программы в консоль

Пожалуйста, дайте мне знать, почему он повторяет один и тот же индекс (3) дважды вместо того, чтобы, скажем, 3 и 20, как должны возвращаться десятицентовики из списка.

Ответы [ 4 ]

1 голос
/ 11 июля 2020

Ответ на ваш непосредственный вопрос, почему он печатает 3 оба раза, заключается в том, что функция IndexOf() возвращает индекс первого элемента в списке , который соответствует вашему условию. Другими словами, представьте это как FirstIndexOf(). Пожалуйста, прочтите связанную документацию для более подробной информации.

После этого позвольте мне немного прокомментировать ваш код. Вы можете сделать это так, как пытаетесь, но это немного запутано и излишне. Есть более простые способы.

Вариант 1

У нас может быть вторичный List<int> для хранения всех найденных индексов (если они есть). Затем выполните итерацию по списку, и если мы найдем соответствующий элемент, сохраним его в списке индекса. Я собираюсь избавиться от всего беспорядка и предположу, что в переменной userMoneyLower пользовательский ввод преобразован в нижний регистр.

string userMoneyLower = "dime";

var indices = new List<int>();
for (int i = 0; i < moneyList.Count; i++)
{
    if (moneyList[i] == userMoneyLower)
    {
        // If we find a matching item, we store the index
        indices.Add(i);
    }
}

if (indices.Count == 0)
{
    // not in list
}
else
{
    // found 1 or more times
}

Далее, если вам разрешено и / или вы хотите , вы можете использовать LINQ и выполнить все это в одной строке кода.

Вариант 2

var indices2 = moneyList
            .Select((val, index) => val == userMoneyLower ? index : -1)
            .Where(x => x != -1)
            .ToList();

Пояснение:

  • Метод Select() сообщает ему go по списку, а выбирает индекс каждого элемента.
  • Но есть предостережение; он заменяет индекс на -1, если элемент в этом индексе не соответствует userMoneyLower.
  • Таким образом, в конце Select() у вас будет список целых чисел со значениями, содержащими -1 , или value >= 0.
  • Следующий Where() говорит ему выполнить своего рода фильтрацию и выбрать только те значения, которые не являются -1.
  • Последние ToList() просто преобразует его в список.
1 голос
/ 11 июля 2020

IndexOf () вернет индекс первого появления элемента в списке. https://www.w3schools.com/jsref/jsref_indexof_array.asp

1 голос
/ 11 июля 2020

IndexOf() будет искать указанный объект и возвращать индекс его первого вхождения в одномерном массиве или в диапазоне элементов в массиве.

https://docs.microsoft.com/en-us/dotnet/api/system.array.indexof?view=netcore-3.1

Может быть, вам стоит попробовать Contains()?

1 голос
/ 11 июля 2020

Я вижу вашу проблему, я попытаюсь объяснить:

Почему он печатает 3 дважды:

Когда программа выполняет итерацию , он сначала видит, что вы набрали Dime. Таким образом, он перейдет к оператору if и go «о, ввод равен этому текущему значению итерации» и выплюнет 3, поскольку это 4-й элемент в списке (C# коллекции - 0 на основе индекса, что означает элемент 1 в коллекция имеет индекс 0). Насколько я могу судить, это ожидаемое поведение. Ваша проблема в том, что когда вы увидите, что ваш ввод равен 2-му вхождению «Dime», он снова получит индекс, однако C# не знает, какой из них вы хотите, поэтому возвращает первое его вхождение, которое - это индекс 3, и поскольку Dime появляется дважды, вы дважды напечатаете 3.

Что касается другой вашей проблемы:

Программа сообщает, что она не удалась потому что во время итерации первый элемент не равен вашему вводу, поэтому он отмечает isNotInList как истинный и никогда не устанавливает значение false снова, если элемент найден. Что вам, вероятно, следует сделать, так это вырваться из l oop, когда вы найдете соответствующий элемент, и установить isNotInList в false, когда вы это сделаете.

...