【问题标题】:Searching in string collection在字符串集合中搜索
【发布时间】:2012-07-06 14:49:46
【问题描述】:

我有这种格式的字符串: "a = 23, b = 432, f = 321, gfs = 413, d = 42, k = 4242, t = 4314, (...etc...)" - 大约 30 个元素

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

例如口头查询:give me all string where a = 3, b, = 2, d = 31, k = 1

我应该使用什么样的集合?想要我应该创建什么样的课程?有什么想法吗?

【问题讨论】:

  • 那么上述查询的结果是什么?

标签: c# linq search collections


【解决方案1】:

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

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

现在您可以使用 LINQ 来获取这样的项目:

var keys = new[] {"a", "b", "d", "k"};
var vals = new[] {3, 2, 31, 1};
var res = data.Where(str => HasAll(str, keys, vals)).ToList();

【讨论】:

    【解决方案2】:

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

    这里是一些代码示例

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

    【讨论】:

    • 您建议他为他必须搜索的每个字符串创建一个字典?
    • OP 想要在 许多 个字符串中搜索 特定值,并希望 所有字符串 满足这些值。
    • @NominSim 然后,您希望使用提供的方法将每个字符串解析为字典,并过滤包含所需键/值对的字典。这仍然是一个很好的方法,即使它不完整。在我看来,OP 可以从这里拿走它已经足够了。
    • 他说他有大约 30 个值“...大约 30 个元素”,格式为 X = Y , ...., X30 = Y30。然后他得到另一个字符串,需要在 find a,b,d & k 中搜索它们的值
    • @Nir 但是有N个字符串,每个有30个值,意思是N个字典。
    【解决方案3】:

    如果我正确理解了问题,应该这样做

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

    【讨论】:

      【解决方案4】:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-06-09
        • 1970-01-01
        • 1970-01-01
        • 2010-11-28
        • 2014-02-18
        • 2015-01-07
        • 2017-04-09
        相关资源
        最近更新 更多