具有多个子字符串的C#字符串搜索
因此,我正在为资源列表设计一个过滤器,其中一个过滤器是Name属性(string) 举个(哑)例子:资源名是“大的,红色/方形表”,过滤器是“红色表”,它应该是一个有效的资源 这就是我能用我仅有的一点时间想到的:具有多个子字符串的C#字符串搜索,c#,string,search,C#,String,Search,因此,我正在为资源列表设计一个过滤器,其中一个过滤器是Name属性(string) 举个(哑)例子:资源名是“大的,红色/方形表”,过滤器是“红色表”,它应该是一个有效的资源 这就是我能用我仅有的一点时间想到的: static void ApplyNameFilter(参考ApplicationViewModel模型,字符串过滤器) { if(string.IsNullOrEmpty(filter)| | filter==“”)返回; 字符[]分隔符={“”、'、'、'.'、'/'、'\\'、'
static void ApplyNameFilter(参考ApplicationViewModel模型,字符串过滤器)
{
if(string.IsNullOrEmpty(filter)| | filter==“”)返回;
字符[]分隔符={“”、'、'、'.'、'/'、'\\'、'\\'、'\'、'\'、'-'};
var validResources=新列表();
foreach(model.ResourcesViewModel.Resources中的var资源)
{
变量过滤器子串=
滤波器
.ToLower()
.分离(分离器)
.ToList();
var资源子串=
资源名称
.ToLower()
.分离(分离器)
.ToList();
ResourceSubstring.ForEach(substring=>{
if(过滤器子字符串包含(子字符串))
filterSubstrings.RemoveAll(sub=>sub==substring);
});
if(filterSubstrings.Count==0)
validResources.Add(资源);
}
model.ResourcesViewModel.Resources=validResources;
}
我应该采取不同的方法吗
编辑:
在我弄明白正则表达式之前,我一直在做这个
static void ApplyNameFilter(参考ApplicationViewModel模型,字符串过滤器)
{
if(string.IsNullOrEmpty(filter))返回;
字符[]分隔符={“”、'、'、'.'、'/'、'\\'、'\\'、'\'、'\'、'-'};
变量过滤器子串=
滤波器
.ToLower()
.分离(分离器)
.ToList();
var validResources=model.ResourcesViewModel.Resources
.Where(resource=>filterSubstrings.All(fs=>resource.Name.ToLower().Contains(fs)))
.ToList();
model.ResourcesViewModel.Resources=validResources;
}
您可以使用LINQ使其更简洁(并且可能更快,因为您正在创建列表,并且不必要地删除每个资源上的元素,尽管非LINQ解决方案可能更快)
如果您愿意接受名称
中的所有筛选器子字符串,而不考虑分隔符
,则可以简化为:
var validResources = model.ResourcesViewModel.Resources
.Where(resource => filterSubstrings.All(fs => resource.Name.ToLower().Contains(fs)))
.ToList();
是 啊一定要考虑一个regex
解决方案——你肯定会有更简洁的代码。还有其他方法可以剥这只猫的皮,但你必须回到你的comp sci 101过去,思考动态编程(至少我想到的是,哈哈)。在这里,基于单一责任原则的方法也可能让你的生活成为一个较小的地狱。在regex
和非regex方法中,尝试利用基于不变性的方法。你以后会很感激你没有改变现状。不过我没有用太多正则表达式,我知道它非常强大。有没有一种方法可以根据输入生成适当的正则表达式模式?@Xeyth,添加code4life极好的注释。我还将澄清,关于具体的一点,如果您正在使用的方法只需要资源列表,那么您不希望让该方法“知道”您的所有对象及其层次结构。这样做的一些原因是:为了防止层次结构发生变化,或者您希望在应用程序的其他部分使用此逻辑。你不需要传递方法不关心的东西,你也不应该传递。@Xeyth:当然。如果使用.NET4.5或更高版本,则更容易利用字符串插值。例如,$“{your variable here}regex expression here”
——这只是一个非常原始的现成示例。我强烈建议你用谷歌搜索正则表达式,你不需要一个非常复杂的正则表达式来完成你想做的事情。@Xeyth,如果你只想“美化”你的方法,你可以使用.Intersect
或.All
,它是不可变的,而且几乎可以给你解决方案。e、 g:filterSubstrings.Intersect(resourceSubstrings.Count()==filterSubstrings.Count
或filterSubstrings.All(fs=>resourceSubstrings.Contains(fs))
。此外,您不需要在每次迭代中计算filterSubstring
,它们不会改变。所以把他们从你的循环中排除。
var validResources = model.ResourcesViewModel.Resources
.Where(resource => filterSubstrings.All(fs => resource.Name.ToLower().Contains(fs)))
.ToList();