Click here to Skip to main content
15,887,746 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more: , +
I have method where I call another API. From
var activeCustomers = await response.Content.ReadAsStringAsync();
I get string which contains [timestamp, value] objects:

{"values":[[1298937600000,1],[1459468800000,16],[1462060800000,527],[1464739200000,173],[1467331200000,132],[1470009600000,166],[1472688000000,151],[1475280000000,172],[1477958400000,139],[1480550400000,129],[1483228800000,116],[1485907200000,133],[1488326400000,180],[1491004800000,227],[1493596800000,281],[1496275200000,263],[1498867200000,230],[1501545600000,326],[1504224000000,403],[1506816000000,442],[1509494400000,1019],[1512086400000,650],[1514764800000,708],[1564617600000,2614],[1567296000000,2527],[1569888000000,3144],[1572566400000,3075],[1575158400000,2541],[1577836800000,2246],[1580515200000,2456],[1583020800000,885]]}


I want to parse these values into Dictionary, but I am not sure what's the most optimal way for that.

What I have tried:

I tried <pre>var results = ((IEnumerable) propertyValue).Cast<object>()
but the ienumerable was one big string. Maybe there's some regex for that?
Posted
Updated 8-Jul-20 23:02pm
Comments
Maciej Los 7-Jul-20 15:43pm    
This looks like json data. Read about json serialization.
Luc Pattyn 7-Jul-20 15:48pm    
Maybe not everything can or should be solved in a single line of code.

This article will show you a possible way: JSON APIs.

:)

If you're using JSON.NET[^], you can use a custom converter to map your property to a dictionary:
C#
public sealed class ArrayToDictionaryConverter : JsonConverter<Dictionary<long, long>>
{
    public override void WriteJson(JsonWriter writer, Dictionary<long, long> value, JsonSerializer serializer)
    {
        if (value is null)
        {
            writer.WriteNull();
            return;
        }
        
        writer.WriteStartArray();
        foreach (var pair in value)
        {
            writer.WriteStartArray();
            writer.WriteValue(pair.Key);
            writer.WriteValue(pair.Value);
            writer.WriteEndArray();
        }
        writer.WriteEndArray();
    }
    
    public override Dictionary<long, long> ReadJson(JsonReader reader, Type objectType, Dictionary<long, long> existingValue, bool hasExistingValue, JsonSerializer serializer)
    {
        var result = existingValue ?? new Dictionary<long, long>();
        long[][] array = serializer.Deserialize<long[][]>(reader);
        if (array != null)
        {
            for (int index = 0; index < array.Length; index++)
            {
                long[] pair = array[index];
                if (pair != null && pair.Length == 2)
                {
                    long key = pair[0];
                    long value = pair[1];
                    result[key] = value;
                }
            }
        }
        
        return result;
    }
}
Usage:
C#
public sealed class Root
{
    [JsonProperty("values")]
    [JsonConverter(typeof(ArrayToDictionaryConverter))]
    public Dictionary<long, long> Values { get; set; }
}

string json = ...;
Root parsedValue = JsonConvert.DeserializeObject<Root>(json);
Dictionary<long, long> values = parsedValue.Values;

You can also do something similar with the new System.Text.Json libraries:
How to write custom converters for JSON serialization - .NET | Microsoft Docs[^]
 
Share this answer
 
Comments
Maciej Los 8-Jul-20 5:55am    
5ed!

If your string has a fixed format, you could try something like this. Firstly, trim your string, remove, {"values":[[ from the start and ]]} from the end. Then do this sort of thing.


C#
Dictionary<long, int> testDict = new Dictionary<long, int>();
 string trimmed = "1298937600000,1],[1459468800000,16],[1462060800000,527],[1464739200000,173";
 var pairs = trimmed.Split("],[");
 foreach(var p in pairs)
 {
     var t = p.Split(',');
     testDict.Add(long.Parse(t[0]), int.Parse(t[1]));
 }
 //An alternative using fluent syntax
 var dictionary = trimmed.Split("],[").Select(s =>
  (Stamp: long.Parse(s.Substring(0, s.IndexOf(","))),
  Value: int.Parse(s.Substring(s.IndexOf(",") + 1)))
  ).ToDictionary(t => t.Stamp, t => t.Value);
 
Share this answer
 
v2

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900