C# 在字符串集合中搜索

C# 在字符串集合中搜索,c#,linq,search,collections,C#,Linq,Search,Collections,我有以下格式的字符串: “a=23,b=432,f=321,gfs=413,d=42,k=4242,t=4314,(…等等)”-大约30个元素 我需要有搜索的可能性,在许多字符串相应的4个元素,例如:a,b,d,k 例如,口头查询:给出所有字符串,其中a=3,b,=2,d=31,k=1 我应该使用什么样的收藏?想要创建什么样的类?有什么想法吗?如果你知道你的值是唯一的,我会构造一个哈希表,其中equal的左边是你的键,右边是你的值。这将帮助您避免任何可能改变的字符串形式,例如额外的空格等 下面是

我有以下格式的字符串:
“a=23,b=432,f=321,gfs=413,d=42,k=4242,t=4314,(…等等)”
-大约30个元素

我需要有搜索的可能性,在许多字符串相应的4个元素,例如:a,b,d,k

例如,口头查询:
给出所有字符串,其中a=3,b,=2,d=31,k=1


我应该使用什么样的收藏?想要创建什么样的类?有什么想法吗?

如果你知道你的值是唯一的,我会构造一个哈希表,其中equal的左边是你的键,右边是你的值。这将帮助您避免任何可能改变的字符串形式,例如额外的空格等

下面是一些代码示例

static void Main(string[] args)
{
    string str = "a = 23, b = 432, f = 321, gfs = 413, d = 42, k = 4242, t = 4314";
    Dictionary<string,string> dictionary = ConstructDictionary(str);
    // Now you can find what you want in your dictionary
}

private static Dictionary<string,string> ConstructDictionary(string str)
{
    string[] pairs = str.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); // this will give you all the pairs X = Y
    Dictionary<string, string> dictionary = new Dictionary<string, string>();
    foreach (string pair in pairs)
    {
        string[] keyValue = pair.Split(new char[] { '=' }, StringSplitOptions.RemoveEmptyEntries); // this will create an array of size 2 where 
        array[0] = key and array[1] = value;
        string key = keyValue[0].Trim();
        string value = keyValue[1].Trim();
        if (!dictionary.ContainsKey(key))
        {
            dictionary.Add(key, value);
        }
    }
    return dictionary;
}
static void Main(字符串[]args)
{
string str=“a=23,b=432,f=321,gfs=413,d=42,k=4242,t=4314”;
字典=构造字典(str);
//现在你可以在字典里找到你想要的
}
私有静态字典(字符串str)
{
string[]pairs=str.Split(新字符[]{',},StringSplitOptions.removeMptyEntries);//这将为您提供所有对X=Y
字典=新字典();
foreach(成对的字符串对)
{
string[]keyValue=pair.Split(新字符[]{'=},StringSplitOptions.RemoveEmptyEntries);//这将创建一个大小为2的数组,其中
数组[0]=键,数组[1]=值;
字符串key=keyValue[0]。Trim();
字符串值=键值[1]。Trim();
如果(!dictionary.ContainsKey(键))
{
添加(键、值);
}
}
返回字典;
}

这里有一种使用辅助功能的方法:

private static bool HasAll(string s, string[] keys, int[] vals) {
    if (keys.Length != vals.Length) throw new ArgumentException("vals");
    var tt = s.Split(new[] {' ', ',', '='});
    for(var i = 0 ; i != keys.Length ; i++) {
        var pos = Array.IndexOf(tt, keys[i]));
        if (pos < 0 || pos == vals.Length-1 || !tt[i+1].Equals(vals[i].ToString())) {
            return false;
        }
    }
    return true;
}

类似这样的查询可以工作,但我建议将值放入与字符串不同的数据结构中。可能是一个具有元素名称的结构,以便可以查找多个值

string s1 = "a = 32, b = 432, f = 321, gfs = 43, d = 42, k = 4, t = 44";
string s2 = "a = 23, b = 432, f = 321, gfs = 413, d = 42, k = 4242, t = 4314";
string s3 = "a = 23, b = 21, f = 321, gfs = 413, d = 42, k = 4242, t = 4314";
var array = new string[] { s1, s2, s3 };

var result = array.Where(s => s.Contains("f = 321") && s.Contains("b = 432"));

如果我正确理解了这个问题,这个就可以了

1) 创建一个字典,其中键是完整字符串,值是字符串的拆分部分

2) 检查标准和工件的交点。交叉口大小与标准大小相同,我们有一个匹配项

[TestMethod]
public void FindValuesInStrings() {

  var strings = new[] {
     "a = 23, b = 432, f = 321, gfs = 11, d = 42, k = 4242, t = 4314",   //A
     "a = 12, b = 123, f = 456, gfs = 11, d = 42, k = 4242, t = 4314",   //B
     "a = 11, b = 456, f = 789, gfs = 413, d = 42, k = 4242, t = 4314",  //C
     "a = 23, b = 789, f = 12,  gfs = 13, d = 42, k = 4242, t = 4314",   //D
  };


   var dict = new Dictionary<string, IEnumerable<string>>();
   foreach (var str in strings) {
      dict.Add(str, str.Split(',').Select(s => s.Trim()));
   }


   // finds the two entries where a = 23 (A & D)
   var criteria = new[] { "a = 23" };
   var found = dict.Where(entry => 
       entry.Value.Intersect(criteria).Count() == criteria.Count()).Select(entry => entry.Key);

   Assert.AreEqual(2, found.Count());

   // finds the single entry where a = 23 and gfs = 11 (A)
   criteria = new[] { "a = 23", "gfs = 11" };
   found = dict.Where(entry => 
        entry.Value.Intersect(criteria).Count() == criteria.Count()).Select(entry => entry.Key);

   Assert.AreEqual(1, found.Count());

}
[TestMethod]
public void FindValuesInStrings(){
var strings=new[]{
“a=23,b=432,f=321,gfs=11,d=42,k=4242,t=4314”
“a=12,b=123,f=456,gfs=11,d=42,k=4242,t=4314”,//b
“a=11,b=456,f=789,gfs=413,d=42,k=4242,t=4314”
“a=23,b=789,f=12,gfs=13,d=42,k=4242,t=4314”
};
var dict=新字典();
foreach(字符串中的var str){
dict.Add(str,str.Split(',).Select(s=>s.Trim());
}
//查找a=23(a&D)的两个条目
var标准=新[]{“a=23”};
var found=dict.Where(条目=>
entry.Value.Intersect(criteria.Count()==criteria.Count()).Select(entry=>entry.Key);
Assert.AreEqual(2,find.Count());
//查找a=23和gfs=11(a)的单个条目
标准=新[]{“a=23”,“gfs=11”};
found=dict.Where(条目=>
entry.Value.Intersect(criteria.Count()==criteria.Count()).Select(entry=>entry.Key);
Assert.AreEqual(1,find.Count());
}

那么,您上述查询的结果是什么?您建议他为他必须搜索的每个字符串创建一个字典?OP希望在许多字符串中搜索特定值,并希望所有满足这些值的字符串。@NominSim然后您希望将每个字符串解析为一个字典,使用提供的方法,并筛选包含所需键/值对的词典。这仍然是一个很好的方法,即使它是不完整的。在我看来,OP可以从这里得到它已经足够了。他说他有大约30个值,“…大约30个元素”,来自X=Y,…,X30=Y30的格式。然后他得到另一个字符串,需要搜索它们的值,如find a、b、d&k@Nir但是有N个字符串,每个字符串有30个值,这意味着N个字典。
[TestMethod]
public void FindValuesInStrings() {

  var strings = new[] {
     "a = 23, b = 432, f = 321, gfs = 11, d = 42, k = 4242, t = 4314",   //A
     "a = 12, b = 123, f = 456, gfs = 11, d = 42, k = 4242, t = 4314",   //B
     "a = 11, b = 456, f = 789, gfs = 413, d = 42, k = 4242, t = 4314",  //C
     "a = 23, b = 789, f = 12,  gfs = 13, d = 42, k = 4242, t = 4314",   //D
  };


   var dict = new Dictionary<string, IEnumerable<string>>();
   foreach (var str in strings) {
      dict.Add(str, str.Split(',').Select(s => s.Trim()));
   }


   // finds the two entries where a = 23 (A & D)
   var criteria = new[] { "a = 23" };
   var found = dict.Where(entry => 
       entry.Value.Intersect(criteria).Count() == criteria.Count()).Select(entry => entry.Key);

   Assert.AreEqual(2, found.Count());

   // finds the single entry where a = 23 and gfs = 11 (A)
   criteria = new[] { "a = 23", "gfs = 11" };
   found = dict.Where(entry => 
        entry.Value.Intersect(criteria).Count() == criteria.Count()).Select(entry => entry.Key);

   Assert.AreEqual(1, found.Count());

}