[英]What is the best way to see if Dictionary string values contain some pattern and at the same time doesn't contain another in C#?
假设我有一个字典Dictionary<string,sting>.
我想看看此字典的字符串值是否包含某些字符串模式,比如说“ abc”,但同时不包含模式“ def”和“ ghi”。 另外,我希望此检查不区分大小写。
我可以这样写:
var options = new Dictionary<string,string>();
...
if (!options.Any(kvp1 => (kvp1.Value.Contains("def", StringComparison.InvariantCultureIgnoreCase))
&& !options.Any(kvp2 => kvp2.Value.Contains("ghi", StringComparison.InvariantCultureIgnoreCase))
&& options.Any(kvp3 => kvp3.Value.Contains("abc", StringComparison.InvariantCultureIgnoreCase)) ))
{
Do Something...
}
所以我想知道,是否有更优雅的方法来执行这种操作?
UPD:此代码肯定存在错误。 我想要的是检查值列表是否至少包含一个包含“ abc”的元素,而根本没有包含“ def”和“ ghi”的元素。 因此,编辑了一下代码。
尝试这个
var options = new Dictionary<string, string>();
var includedValues = new[] { "abc", "dfg" };
var excludedValues = new[] { "hij", "klm" };
var cultureInf = CultureInfo.CurrentCulture;
var containsPredicate = new Func<string, string, bool>((s1, s2) => {
return cultureInf.CompareInfo.IndexOf(s1, s2, CompareOptions.IgnoreCase)>=0;
});
if (
includedValues.All(v => options.Values.Any(kv =>containsPredicate(kv, v)))
&&
excludedValues.All(v => !options.Values.Any(kv =>containsPredicate(kv, v))))
{
// do smthg
}
有很多事情要照顾。 基于文化的不区分大小写的比较和动态的,非硬编码的模式,例如:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Globalization;
namespace ConsoleApplication7
{
internal static class Program
{
internal static void Main(string[] args)
{
var options = new Dictionary<string, string>();
var compareCulture = CultureInfo.CurrentCulture;
var patternsNeeded = new[] { "abc", "def" };
var patternsForbidden = new[] { "ghi", "xxx" };
Func<KeyValuePair<string, string>, bool> meetsCriteria =
kvp => patternsNeeded.Any(p => compareCulture.CompareInfo.IndexOf(kvp.Value, p, CompareOptions.IgnoreCase) >= 0)
&& !patternsForbidden.Any(p => compareCulture.CompareInfo.IndexOf(kvp.Value, p, CompareOptions.IgnoreCase) >= 0);
var dictionaryContainsHits = options.Any(meetsCriteria);
}
}
}
如果您的词典很大,则可能需要在此处和此处都.AsParallel()
。 由于这些都是读取操作,因此应该可以正常工作。
不确定是否要使用.Any()
或.All()
作为肯定列表中的模式。 选择适合您的用例的一种。
您可以通过字典对象上的Values属性直接访问值。
好了,您可以创建自己的linq来执行此方法:
public static class ExtendedLinq
{
public static bool All<T>(this IEnumerable<T> source, params Func<T, bool>[] conditions)
{
foreach (var condition in conditions)
if (!source.Any(condition))
return false;
return true;
}
}
然后用法:
var options = new Dictionary<string, string>();
if (options.Values.All((t => t.Contains("abc")), (t => !t.Contains("def")), (t => !t.Contains("ghi"))))
{
// Do something
}
希望它最终是您想要的。
顺便说一句,其中包含不区分大小写的内容不属于框架的一部分,所以我没有包括它,因为您已经拥有它。
旧的(误解了这个问题):var options = new Dictionary(); if(options.Values.Any(t => t.Contains(“ abc”)&&!t.Contains(“ def”)&&!t.Contains(“ ghi”))){//做某事}
我建议你这样做:
var dictionaryVal = d.Select(p => p.Value.ToLower());
string string1 = "string1";
string string2 = "string2";
string string3 = "string3";
if (dictionaryVal.Contains(string1.ToLower())&&dictionaryVal.Contains(string2.ToLower())&&dictionaryVal.Contains(string3.ToLower()))
{
//your code here
}
那就是看看字典的值是否包含string1但不包含string2和string3。但是...
如果您要检查单个词典项,并针对同一项的值检查所有3个字符串,则为:
if (d.Any(p => p.Value.Contains(string1.ToLower()) && !p.Value.Contains(string2.ToLower()) && !p.Value.Contains(string3.ToLower())))
{
// your code here
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.