У меня есть список строк следующим образом:
List<string> str = new List<string>() { "7, 31", "2, 4", "5, 6" };
Мой ввод будет что-то вроде "1, 2" или "1"
Есть ли способ сравнить, совпадает ли какой-либо элемент в списке строк с вводом. В приведенном выше случае он должен вернуть false. Но если мой ввод был «31», он должен дать мне истину, или если мой ввод был «7, 31», он также должен дать истину.
Я пробую этот код, но он всегда возвращает true. Пожалуйста помоги.
bool res = false;
List<string> substrings = new List<string>() { "7, 31", "2, 4", "5, 6" };
string input = "1"; //Because my input can be "1" or "1, 31" etc spltting it.
var inputSplitted = input.Split(',');
var plates = substrings.Select(x => x.Split(','));
foreach (var item in plates)
{
if (item.Any() == inputSplitted.Any())
{
res = true;
}
}
Console.WriteLine(res);
item
и inputSplitted
являются массивами string
, поэтому Any
, вызываемый для них, просто проверяет, не пусты ли эти массивы (т. е. есть ли в них какие-либо строки), что всегда будет оцениваться как true
для предоставленных примеров.
Если я правильно понимаю правило - ввод должен быть представлен либо как полная строка в исходной коллекции, либо как часть исходной коллекции, разделенной запятой - вы должны сравнивать строки в коллекциях. Быстрое исправление будет использовать SequenceEqual
с дополнительной обработкой входных данных одного элемента (также кажется, что вам нужно вызвать .Select(s => s.Trim()).ToArray()
для обоих результатов разделения):
if (item.SequenceEqual(inputSplitted)
|| (inputSplitted.Length == 1 && item.Contains(inputSplitted.First())))
{
res = true;
}
Но в целом это приведет к снижению производительности, если такие поиски будут выполняться несколько раз. Я бы рекомендовал использовать HashSet
для такого поиска:
var hash = substrings
.SelectMany(s => s.Split(",").Select(s => s.Trim())) // flatten split strings
.Concat(substrings) // and concatenate with original
.ToHashSet();
var res = hash.Contains(input); // search in collection (should be prepared one time)
Если порядок элементов не важен (например, «7, 31» и «31, 7» одинаковы), вы можете перестроить строки поиска и ввода, разделив их и используя OrderBy(s => s)
на результатах разделения перед объединением обратно.
У Гуру Строна есть отличный ответ. Простым и удобочитаемым решением вашей проблемы было бы получить пользовательский ввод, разделить его (и обрезать) и сделать то же самое со списком строк для проверки, а затем просто сделать что-то вроде
inputSplitted.All(s => plates.Contains(s));
Или с группой методов: inputSplitted.All(plates.Contains);
Это предполагает, что я правильно понял ваш вопрос, и что порядок ввода и т. д. не имеет значения. Вы просто хотите узнать, есть ли в списке где-то каждое число, которое написал пользователь.