搜索具有键值对象的数组的数组

时间:2019-04-15 23:08:47

标签: c# .net

我正在使用一个返回如下JSON的API:

    {
        "lookup_table_data": [
            [
                {
                    "key": "id",
                    "value": 0
                },
                {
                    "key" : "label",
                    "value" : "something"
                }
            ],
            [
                {
                    "key": "id",
                    "value": 1
                },
                {
                    "key" : "label",
                    "value" : "something_else"
                }
            ]
       ]
  }

我创建了一个将json对象反序列化为的类,如下所示:

public class LookupResponseModel
    {
        public Lookup_Table_Data[][] Lookup_table_data { get; set; }

        public class Lookup_Table_Data
        {
            public string Key { get; set; }
            public object Value { get; set; }
        }
    }      

现在想象一下,JSON响应具有超过1000条记录,而不是我在示例中给出的2条记录。

我想搜索模型并能够找到键“ id”的值等于1的位置-因为我想使用标签键值“ something_else”。

该模型如何获取ID为1的标签“ something_else”?

4 个答案:

答案 0 :(得分:1)

我建议采用这样的方法:

public class LookupResponseModel
{
    public Lookup_Table_Data[][] Lookup_table_data { get; set; }

    public class Lookup_Table_Data
    {
        public string Key { get; set; }
        public object Value { get; set; }
    }
}

// This will help compare the values and convert if necessary
// This part was missing from my original answer and made it not work
bool ObjectCompare(object a, object b)
{
    if (object.Equals(a, b))
    {
        return true;
    }
    else
    {
        var altB = Convert.ChangeType(b, Type.GetTypeCode(a.GetType()));
        return object.Equals(a, altB);
    }
}

// This will break the result up into an Array of Dictionaries
// that are easier to work with
Dictionary<string, object>[] MakeTables(LookupResponseModel lrm)
{
    return lrm.Lookup_table_data.Select( entry => entry.ToDictionary( e => e.Key, e => e.Value ) ).ToArray();
}

// This will help you find the dictionary that has the values you want
Dictionary<string, object> FindTable( Dictionary<string, object>[] tables, string key, object value )
{
    return tables.Where( dict => dict.TryGetValue(key, out object val) && ObjectCompare(value, val) ).FirstOrDefault(); 
}

// Here is how you might use them together
string GetLabel()
{
    var lrm = JsonConvert.DeserializeObject<LookupResponseModel>(json);
    var lookup = MakeTables(lrm);

    var table = FindTable( lookup, "id", 1 );

    return table["label"].ToString();  // Returns "something_else"
}

答案 1 :(得分:1)

var lookup = model.lookupTableData.Select(data => new { key = (long)data.First(kvp => kvp.Key == "id").Value, value = (string)data.First(kvp => kvp.Key == "label").Value).ToDictionary(kvp => kvp.key, kvp => kvp.value)
var displayText = lookup[1]; // "something_else"

我通过电话尝试的语法可能不是100%正确。

答案 2 :(得分:0)

简单的答案是,你说这样的话

public class LookupResponseModel
{
  public LookupTableData[][] lookupTableData { get; set; }

  public class LookupTableData
  {
      public string Key { get; set; }
      public object Value { get; set; }
  }

  public LookupTableData[] FindById( int id )
  {
    if (this.lookupTableData == null) throw new InvalidOperationException();

    foreach ( LookupTableData[] entry in lookupTableData )
    {
      if (entry != null)
      {
        foreach( LookupTableData item in entry )
        {
          bool isMatch =  "id".Equals( item.Key ?? "", StringComparison.Ordinal )
                       && item.Value is int
                       && ((int)item.Value) == id
                       ;
          if ( isMatch )
          {
            return entry;
          }
        }
      }
    }
    return null;
  }

}

答案 3 :(得分:0)

数据:

LookupResponseModel model = new LookupResponseModel();

model.Lookup_table_data = new LookupResponseModel.Lookup_Table_Data[][]
{
    new LookupResponseModel.Lookup_Table_Data[]
    {
        new LookupResponseModel.Lookup_Table_Data(){Key = "id", Value = "0"},
        new LookupResponseModel.Lookup_Table_Data(){Key = "label", Value = "hello"},
        new LookupResponseModel.Lookup_Table_Data(){Key = "textbox", Value = "bye"}
    },
    new LookupResponseModel.Lookup_Table_Data[]
    {
        new LookupResponseModel.Lookup_Table_Data(){Key = "id", Value = "1"},
        new LookupResponseModel.Lookup_Table_Data(){Key = "label", Value = "banana"},
        new LookupResponseModel.Lookup_Table_Data(){Key = "textbox", Value = "potatoe"}
    },
    new LookupResponseModel.Lookup_Table_Data[]
    {
        new LookupResponseModel.Lookup_Table_Data(){Key = "id", Value = "2"},
        new LookupResponseModel.Lookup_Table_Data(){Key = "label", Value = "cat"},
        new LookupResponseModel.Lookup_Table_Data(){Key = "textbox", Value = "bydog"}
    }
};

此查询为我们提供第二组(全部3个Lookup_Table_Data,其中键为ID,值为1)仍然为[] [],并且可以包含多个结果:

var _result = model.Lookup_table_data.Where(x => x.Any(y => y.Key == "id" && y.Value.Equals("1")));

这将为您提供上一组“标签”键的确切值(键=“标签”,值=“香蕉”):

var _exactlyLabel = _result.Select(x => x.Where(y => y.Key == "label"));

或者您可以将_result.SelectMany(...设置为[]而不是[] []