我有一个 strings 列表如下,
List<string> str = new List<string>() { "7, 31", "2, 4", "5, 6" };
我的输入将类似于“1、2”或“1”
有没有办法比较 strings 列表中的任何项目是否与输入完全匹配。在上述情况下,它应该返回 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);
回答1
item
和 inputSplitted
是 string
的数组,因此调用它们的 https://docs.microsoft.com/en-us/dotnet/api/system.linq.enumerable.any?view=net-6.0 只是检查这些数组是否不为空(即其中是否有任何 strings)对于提供的示例,它总是会评估为 true
。
如果我正确理解规则 - 输入应该在原始集合中作为完整的 string 或作为以逗号分隔的原始集合的一部分存在 - 你应该比较集合中的 strings 。快速修复将使用 SequenceEqual
对一个元素输入进行额外处理(而且您似乎需要在两个拆分结果上调用 .Select(s => s.Trim()).ToArray()
):
if (item.SequenceEqual(inputSplitted)
|| (inputSplitted.Length == 1 && item.Contains(inputSplitted.First())))
{
res = true;
}
但一般来说,如果多次执行此类搜索,则会导致性能不佳。我建议使用 https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.hashset-1?view=net-6.0 进行此类搜索:
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)
来重建搜索并输入 strings,然后再连接回来。
回答2
Guru Stron 有一个很好的答案。一个简单易读的问题解决方案是获取用户输入,将其拆分(并修剪),并对要检查的 strings 列表执行相同操作,然后执行类似的操作
inputSplitted.All(s => plates.Contains(s));
或使用方法组:inputSplitted.All(plates.Contains);
这假设我正确理解了您的问题,并且输入顺序等无关紧要。你只想知道用户写的每个数字是否在列表中的某个地方。