从 JArray 中获取唯一的列值

Posted

技术标签:

【中文标题】从 JArray 中获取唯一的列值【英文标题】:Fetch Unique Column Values from a JArray 【发布时间】:2021-03-14 06:05:17 【问题描述】:

我试图从 JSON 响应中仅获取唯一 ID。我试图解析并仅选择令牌 ID,但它失败了。 仅获取 ID 的最佳和最快方法是什么?

代码:

JArray jArray = new JArray();
var response = new HttpResponseMessage(System.Net.HttpStatusCode.OK);
response.Content = new StringContent(jArray.ToString(Formatting.Indented)); 
var resp = await response.Content.ReadAsStringAsync();

   

这是我的 JSON 数组示例:

[
  
    "Timestamp": "2020-11-24T08:25:46.6531855Z",
    "ID": "8c316aca-b930-421f-851c-17d618b61fa1",
    "Message": "New User Registered"
  ,
  
    "Timestamp": "2020-11-24T08:25:46.6531855Z",
    "ID": "8c316aca-b930-421f-851c-17d618b61fa1",
    "Message": "User details updated"
  ,
  
    "Timestamp": "2020-11-24T08:25:46.6531855Z",
    "ID": "a23shaga-2wd3-fky6-851c-43524fbfgsa",
    "Message": "New User Registered"
  
]

所需的输出:

8c316aca-b930-421f-851c-17d618b61fa1
a23shaga-2wd3-fky6-851c-43524fbfgsa

【问题讨论】:

最快的方法是使用流式 JsonReader。 Json.NET 非常慢。使用不同的库来处理 json。我想,响应来自 UTF-8 编码 - 使用直接使用这种编码的库。 【参考方案1】:

这将为您提供与 JArray 不同的 ID 值,过滤掉可能的空值:

jArray = JArray.Parse(resp);
var ids = jArray.Children<JObject>()
                .Select(jo => (string)jo["ID"])   // NOTE: this is case sensitive
                .Where(s => s != null)
                .Distinct()
                .ToList();

在这里演示:https://dotnetfiddle.net/gaQ1n0

【讨论】:

【参考方案2】:

最好的方法是创建具有时间戳、id 和消息属性的对象,然后将 json 反序列化为该对象。

但现在你可以试试下面的,应该会很适合你。

JArray jArray = new JArray();          
jArray = JArray.Parse(@"[

    ""Timestamp"": ""2020-11-24T08:25:46.6531855Z"",
    ""ID"": ""8c316aca-b930-421f-851c-17d618b61fa1"",
    ""Message"": ""New User Registered""
,

    ""Timestamp"": ""2020-11-24T08:25:46.6531855Z"",
    ""ID"": ""8c316aca-b930-421f-851c-17d618b61fa1"",
    ""Message"": ""User details updated""
,

    ""Timestamp"": ""2020-11-24T08:25:46.6531855Z"",
    ""ID"":""a23shaga-2wd3-fky6-851c-43524fbfgsa"",
    ""Message"": ""New User Registered""
]");


var newList = jArray.Where(y=> !string.IsNullOrEmpty(y["ID"].ToString()))
            .GroupBy(x => x["ID"])
            .Select(x => x.First()).ToList();


foreach (var item in newList)

    Console.WriteLine(item["ID"]);

这里 newList 只包含唯一数据 w.r.t 'ID' 只需将我示例中的整个字符串替换为您获得的异步响应即可。

注意:您应该使源返回唯一或创建一个新对象并反序列化它而不是使用 JObject,这将在您有更大的列表时为您提供帮助

所以下面是我认为你正在寻找的结果

【讨论】:

感谢@Manti_Core,如果 ID 有任何空值,我想用空值进行过滤。这是行不通的。像 jArray.Where(x => x["Id"] != null).GroupBy(x=>x["Id"]).Select(x => x.First()).ToList() @PavanKumarGVVS 你几乎是正确的,但你需要它是字符串才能比较它。尝试更新答案。

以上是关于从 JArray 中获取唯一的列值的主要内容,如果未能解决你的问题,请参考以下文章

Newtonsoft JArray - 从节点指定的数组中选择多个值

JArray 替换条件匹配的值

C# JArray与JObject 的使用

如何在不添加新 JObject 键/名称的情况下将 JArray 添加到 JObject 中?

如何结合Jarray?

如何访问 JArray 的元素(或迭代它们)