есть ли простой способ узнать наименьшее значение из json без де-сериализации c# - PullRequest
0 голосов
/ 09 мая 2020

У меня ниже json вывод из api. Я хочу найти наименьшее значение среди всех элементов.

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# code-

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

Ответы [ 4 ]

2 голосов
/ 09 мая 2020

Десериализация - это способ go

, вы можете де-сериализовать его в объект и выполнять необходимые вычисления

    // <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 , чтобы получить класс POCO из json (приведенный выше код сгенерирован из этого)

Затем используйте

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;

Вы можете решить, какой элемент вы ищу PS Код не тестировал.

2 голосов
/ 09 мая 2020

Для этого вы можете использовать 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
1 голос
/ 09 мая 2020

Вы можете создавать классы для представления вашего JSON, используя такой инструмент, как quicktype.io :

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, используя Json. NET и используйте MinBy из MoreLinq , чтобы получить минимальные цены на 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

1 голос
/ 09 мая 2020

Вы можете использовать регулярное выражение.

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

То же для низкого значения.

...