简体   繁体   English

从具有特定其他属性值的 JObject 中提取 JObject 属性

[英]Pull JObject property from JObject that has specific other property value

I'm relatively fluent using json.net, but I'm struggling to pull this value in a straightforward way.我使用 json.net 相对流利,但我正在努力以直接的方式提取这个值。

I feel like json.net should be able to infer what I'm trying to do so that I don't have to cast every step along the way to get what I want.我觉得 json.net 应该能够推断出我正在尝试做什么,这样我就不必一路走来获得我想要的东西。

Below is my first failed attempt and a second attempt which I got to work.下面是我第一次失败的尝试和我开始工作的第二次尝试。 While the second attempt does work, I'd like to simplify the code to be somewhat more like the first one.虽然第二次尝试确实有效,但我想简化代码,使其更像第一次。

Note that I can't assume that the "C" object is the one that contains the object I want.请注意,我不能假设“C” object 是包含我想要的 object 的那个。

var jt = JToken.Parse(@"{
    ""A"": {
        ""name"": ""object1"",
        ""order"": ""1"",
        ""type"": ""val""
    },
    ""B"": {
        ""order"": ""2"",
        ""type"": ""val"",

    },
    ""C"": {
        ""name"": ""object3"",
        ""type"": ""val"",
        ""answer"": ""Yes"", ""<------ comment"": ""this is the value I'm trying to get""
    }
}");

//var firstAttempt = (jt.First(j => j["name"] == "object3"))["answer"];  // cannot be applied to operands of type 'JToken' and 'String'

var thisWorksFine = jt.First(a => a.ToObject<JProperty>()
                            .Value.ToObject<JObject>()["name"]?.ToString() == "object3")
                            .ToObject<JProperty>()
                            .Value["answer"];

So my question is, is there a way to get the value without having to cast each object/property and ultimately have code that looks more like my first attempt?所以我的问题是,有没有一种方法可以在不必强制转换每个对象/属性的情况下获得价值,并最终获得看起来更像我第一次尝试的代码? If my second attempt is more or less what has to be done, that's fine.如果我的第二次尝试或多或少是必须做的,那很好。

I've used QuickType to make a model of your Json code and then parsed it and did the filtering on the resulting objects which is much easier.我使用QuickType制作了 Json 代码的 model,然后对其进行解析并对生成的对象进行过滤,这更容易。 Code:代码:

public class MyElement
{
    [JsonProperty("name")]
    public string Name { get; set; }

    [JsonProperty("order")]
    public long Order { get; set; }

    [JsonProperty("type")]
    public string Type { get; set; }

    [JsonProperty("answer")]
    public string Answer { get; set; }
}

And parsing:并解析:

string json = @"{
    ""A"": {
        ""name"": ""object1"",
        ""order"": ""1"",
        ""type"": ""val""
    },
    ""B"": {
        ""order"": ""2"",
        ""type"": ""val"",

    },
    ""C"": {
        ""name"": ""object3"",
        ""type"": ""val"",
        ""answer"": ""Yes"",
    }
}";

Dictionary<string, MyElement> elements = JsonConvert.DeserializeObject<Dictionary<string, MyElement>>(json);
string answerOfObject3 = elements.Values.FirstOrDefault(element => element.Name == "object3")?.Answer;

Do you specifically want to always get the answer under the "C" object?您是否特别想始终在“C”object 下得到答案?

If so you can use:如果是这样,您可以使用:

var jToken = JToken.Parse("{\r\n\t\"A\": {\r\n\t\t\"name\": \"object1\",\r\n\t\t\"order\": \"1\",\r\n\t\t\"type\": \"val\"\r\n\t},\r\n\t\"B\": {\r\n\t\t\"name\": \"object2\",\r\n\t\t\"order\": \"2\",\r\n\t\t\"type\": \"val\"\r\n\t},\r\n\t\"C\": {\r\n\t\t\"name\": \"object3\",\r\n\t\t\"type\": \"val\",\r\n\t\t\"answer\": \"Yes\"\r\n\t}\r\n}");

var answer = jToken.SelectToken("C.answer");

You seem to be jumping through more hoops than you need to.你似乎跳过了比你需要的更多的圈子。 I would rewrite your query like this:我会像这样重写您的查询:

var answer = jt.Children<JProperty>()
               .Where(jp => (string)jp.Value["name"] == "object3")
               .Select(jp => (string)jp.Value["answer"])
               .FirstOrDefault();

Fiddle: https://dotnetfiddle.net/blKne6小提琴: https://dotnetfiddle.net/blKne6

The above can be simplified somewhat to the following, which is a little closer to your first attempt:上面可以稍微简化为以下,这更接近您的第一次尝试:

var answer = (string)jt.Children<JProperty>()
                       .FirstOrDefault(jp => (string)jp.Value["name"] == "object3")
                       ?.Value["answer"];

Fiddle: https://dotnetfiddle.net/3Iw8Uu小提琴: https://dotnetfiddle.net/3Iw8Uu

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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