简体   繁体   English

查看字典字符串值是否包含某些模式并且同时在C#中不包含其他模式的最佳方法是什么?

[英]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#?

Let's say I have a dictionary Dictionary<string,sting>. 假设我有一个字典Dictionary<string,sting>.

I want to see if the string values of this dictionary contain some string pattern, let's say "abc" and at the same time doesn't contain patterns "def" and "ghi". 我想看看此字典的字符串值是否包含某些字符串模式,比如说“ abc”,但同时不包含模式“ def”和“ ghi”。 Also, I want this check to be not case sensitive. 另外,我希望此检查不区分大小写。

I can write it like this: 我可以这样写:

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...
        }

So I wonder, is there more elegant way to perform such operation? 所以我想知道,是否有更优雅的方法来执行这种操作?

UPD: This code sure has a bug. UPD:此代码肯定存在错误。 What I desire is to check that values list has at least one element that contains "abc", and no elements at all that has "def" and "ghi". 我想要的是检查值列表是否至少包含一个包含“ abc”的元素,而根本没有包含“ def”和“ ghi”的元素。 So edited code a bit. 因此,编辑了一下代码。

try this 尝试这个

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
}

There are multiple things to take care of. 有很多事情要照顾。 Culture-based case-insensitive comparison and dynamic, non hard-coded patterns for example: 基于文化的不区分大小写的比较和动态的,非硬编码的模式,例如:

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);
    }
  }
}

If your dictionary is large, you may want to throw in an .AsParallel() here and there. 如果您的词典很大,则可能需要在此处和此处都.AsParallel() As those are all read operations, it should work fine. 由于这些都是读取操作,因此应该可以正常工作。

Not sure if you want .Any() or .All() for the patterns that are in your positive list. 不确定是否要使用.Any().All()作为肯定列表中的模式。 Take the one that fits your use case. 选择适合您的用例的一种。

You can directly access values via Values property on the dictionary object. 您可以通过字典对象上的Values属性直接访问值。

Well, you can create your own linq to do this approach: 好了,您可以创建自己的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;
    }
}

and then usage: 然后用法:

var options = new Dictionary<string, string>();
if (options.Values.All((t => t.Contains("abc")), (t => !t.Contains("def")), (t => !t.Contains("ghi"))))
{
    // Do something
}

Hope its finally what you wanted. 希望它最终是您想要的。

Btw, that contains which is case insensitive is not part of the framework, so I didnt include it, since you already have it. 顺便说一句,其中包含不区分大小写的内容不属于框架的一部分,所以我没有包括它,因为您已经拥有它。

old (misunderstood the question): var options = new Dictionary(); 旧的(误解了这个问题):var options = new Dictionary(); if(options.Values.Any(t => t.Contains("abc") && !t.Contains("def") && !t.Contains("ghi"))) { // Do something } if(options.Values.Any(t => t.Contains(“ abc”)&&!t.Contains(“ def”)&&!t.Contains(“ ghi”))){//做某事}

It depends on the context, because it might be usefull to take a look on the Sorted dictionary or Regex classes. 它取决于上下文,因为查看Sorted字典Regex类可能很有用。

i would suggest that you do this : 我建议你这样做:

 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
 }

that is to see if a dictionary's values contain string1 but does not contain string2 and string3.however... 那就是看看字典的值是否包含string1但不包含string2和string3。但是...
if you like to check for a single dictionary item and check all 3 strings against the same item's value it would be : 如果您要检查单个词典项,并针对同一项的值检查所有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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM