有没有一种简单的方法可以在不进行反序列化的情况下从 JSON 中找出最低值?

问题描述 投票:0回答:4

我有以下 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# 中做到这一点?

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);
c# json min
4个回答
2
投票

您可以使用

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
投票

反序列化将是正确的选择

您可以将其反序列化为对象并进行您想要的计算

    // <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 我还没有测试过代码。


1
投票

您可以使用正则表达式。

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;
    }           
}

低价值也同样。


1
投票

您可以使用像 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

© www.soinside.com 2019 - 2024. All rights reserved.