Reputation: 16239
I have below JSON output from API. I want to find out lowest value among all elements.
JSON data:
{
"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
}
]
}
I want to compare all values among JSON element and display lowest value = "low": 112.1
and its own high value. "high": 293.69,
I tried like below using jQuery, but how can I do it in 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);
Upvotes: 0
Views: 776
Reputation: 23278
You may use Newtonsoft.Json.Linq
for that, parse your JSON to JObject
, then get all properties with low
name, find the property with lowest value and get the high
value at the same level
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);
It gives you
"low": 112.1
"high": 293.69
Upvotes: 2
Reputation: 26335
You could create classes to represent your JSON using a tool like 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; }
}
Then deserialize your json using Json.NET, and use MinBy
from MoreLinq to get the minimum prices by Low
. MinBy
will return a IEnumerable<Price>
, so we can iterate each min price and print the Low
and High
properties:
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}");
}
Output:
Min = 112.1, High = 293.69
Full demo on dotnetfiddle.net
Upvotes: 1
Reputation: 404
You could use regex.
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;
}
}
Same for low value.
Upvotes: 1
Reputation: 181
De-serializing it would be the way to go
you can de-serialize it into an object and do the calculations you want
// <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 }
},
};
}
}
you can use Quciktype to get POCO class from the json (The above code is from generated from that)
Then use
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;
You may want to decide what element you are looking for P.S I have not tested the code.
Upvotes: 2