有啥简单的方法可以在不进行反序列化的情况下从 json 中找出最低值 c#
Posted
技术标签:
【中文标题】有啥简单的方法可以在不进行反序列化的情况下从 json 中找出最低值 c#【英文标题】:is there any simple way to find out lowest value from json without doing de-serialization c#有什么简单的方法可以在不进行反序列化的情况下从 json 中找出最低值 c# 【发布时间】:2020-08-25 00:29:50 【问题描述】:我有以下来自 api 的 json 输出。 我想找出所有元素中的最低值。
json 数据 -
"prices": [
"frequency": "daily",
"date": "2020-05-05",
"intraperiod": false,
"open": 295.06,
"high": 301.0,
"low": 294.46,
"close": 297.56
,
"frequency": "daily",
"date": "2020-05-04",
"intraperiod": false,
"open": 289.17,
"high": 293.69,
"low": 112.1,
"close": 293.16
,
"frequency": "daily",
"date": "2020-05-01",
"intraperiod": false,
"open": 286.25,
"high": 299.0,
"low": 222,
"close": 289.07
]
我想比较 json 元素中的所有值并显示最小值 = "low": 112.1
和它自己的高值。 "high": 293.69,
我尝试如下使用 jquery 但我想在 c# 中执行此操作请分享 c# 代码-
function get(arr, prop)
var min;
for (var i=0 ; i<arr.length ; i++)
if (min== null || parseInt(arr[i][prop]) > parseInt(min[prop]))
min= arr[i];
return min;
var min = get(arr, "low");
console.log(min.high);
【问题讨论】:
不,没有反序列化的简单方法可以做到这一点,至少反序列化为某种形式的对象结构? 哦,我明白了,你能帮我提供示例代码吗? 【参考方案1】:您可以为此使用Newtonsoft.Json.Linq
,将您的JSON解析为JObject
,然后获取具有low
名称的所有属性,找到值最低的属性并获取同一级别的high
值
var json = JObject.Parse(jsonString);
var properties = json.DescendantsAndSelf()
.OfType<JProperty>()
.Where(p => p.Name == "low");
var lowProperty = properties
.Aggregate((p1, p2) => p1.Value.Value<double>() < p2.Value.Value<double>() ? p1 : p2);
var highProperty = (lowProperty?.Parent as JObject)?.Property("high");
Console.WriteLine(lowProperty);
Console.WriteLine(highProperty);
它给你
"low": 112.1
"high": 293.69
【讨论】:
【参考方案2】:您可以使用正则表达式。
var pattern = "\"high\": ([0-9]+(\\.[0-9]+)?)";
MatchCollection matches = Regex.Matches(json, pattern);
var max = double.MinValue;
foreach (Match m in matches)
var val = Convert.ToDouble(m.Groups[1].Value);
if (max < val)
max = val;
同样适用于低价值。
【讨论】:
【参考方案3】:反序列化将是要走的路
您可以将其反序列化为一个对象并进行所需的计算
// <auto-generated />
//
// To parse this JSON data, add NuGet 'Newtonsoft.Json' then do:
//
// using QuickType;
//
// var priceData = PriceData.FromJson(jsonString);
namespace QuickType
using System;
using System.Collections.Generic;
using System.Globalization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
public partial class PriceData
[JsonProperty("prices")]
public List<Price> Prices get; set;
public partial class Price
[JsonProperty("frequency")]
public string Frequency get; set;
[JsonProperty("date")]
public DateTimeOffset Date get; set;
[JsonProperty("intraperiod")]
public bool Intraperiod get; set;
[JsonProperty("open")]
public double Open get; set;
[JsonProperty("high")]
public double High get; set;
[JsonProperty("low")]
public double Low get; set;
[JsonProperty("close")]
public double Close get; set;
public partial class PriceData
public static PriceData FromJson(string json) => JsonConvert.DeserializeObject<PriceData>(json, QuickType.Converter.Settings);
public static class Serialize
public static string ToJson(this PriceData self) => JsonConvert.SerializeObject(self, QuickType.Converter.Settings);
internal static class Converter
public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
DateParseHandling = DateParseHandling.None,
Converters =
new IsoDateTimeConverter DateTimeStyles = DateTimeStyles.AssumeUniversal
,
;
你可以使用Quciktype从json中获取POCO类(上面的代码是从那个生成的)
然后使用
var data = PriceData.FromJson(json_string);
var min = data.Select(x=>x.Low).Min();
// There may be multiple Price objects with the same low, I will use the first one
min_object = data.Where(x=>x.Low == min).First()
var high_value_of_min_object = min_object.High;
您可能想决定要查找的元素 P.S 我没有测试过代码。
【讨论】:
【参考方案4】:您可以使用quicktype.io 之类的工具创建类来表示您的 JSON:
public partial class Temperatures
[JsonProperty("prices")]
public List<Price> Prices get; set;
public partial class Price
[JsonProperty("frequency")]
public string Frequency get; set;
[JsonProperty("date")]
public DateTimeOffset Date get; set;
[JsonProperty("intraperiod")]
public bool Intraperiod get; set;
[JsonProperty("open")]
public double Open get; set;
[JsonProperty("high")]
public double High get; set;
[JsonProperty("low")]
public double Low get; set;
[JsonProperty("close")]
public double Close get; set;
然后使用Json.NET 反序列化你的json,并使用MoreLinq 中的MinBy
得到Low
的最低价格。 MinBy
将返回 IEnumerable<Price>
,因此我们可以迭代每个最低价格并打印 Low
和 High
属性:
using Newtonsoft.Json;
using MoreLinq;
...
var deserializedJson = JsonConvert.DeserializeObject<Temperatures>(json);
var minPrices = deserializedJson.Prices.MinBy(price => price.Low);
foreach (var price in minPrices)
Console.WriteLine($"Min = price.Low, High = price.High");
输出:
Min = 112.1, High = 293.69
dotnetfiddle.net 上的完整演示
【讨论】:
以上是关于有啥简单的方法可以在不进行反序列化的情况下从 json 中找出最低值 c#的主要内容,如果未能解决你的问题,请参考以下文章
如何让 Json.Net 在不忽略子属性的情况下从 documentDB 序列化/反序列化动态/通用对象?
如何在不创建组件的情况下从 laravel 刀片视图文件扩展 app.js 方法/数据/手表