2

この形式の文字列があります: "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

どのようなコレクションを使用すればよいですか? 作成するクラスの種類が必要ですか? 何か案は?

4

4 に答える 4

1

補助関数を使用してそれを行う 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();
于 2012-07-06T15:02:18.583 に答える
1

質問を正しく理解していれば、これでうまくいくはずです

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

}
于 2012-07-06T15:43:21.120 に答える
1

値が一意であることがわかっている場合は、等号の左側がキーで右側が値であるハッシュ テーブルを作成します。これにより、余分なスペースなど、変更される可能性のある文字列の形成を避けることができます。

ここにいくつかのコードサンプルがあります

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;
}
于 2012-07-06T14:55:02.757 に答える
0

このクエリのようなものは機能しますが、値を文字列とは異なるデータ構造に配置することをお勧めします。複数の値を検索できるように、要素名を持つ構造体である可能性があります。

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"));
于 2012-07-06T15:07:43.750 に答える