1

So let's say that you have 2 series of data. (Both object arrays, in your choice of a serialized JSON string, or the actual objects).

For Instance:

string str1 = @"{""datapoints"":[[""02/28/2019"",146800.0],[""02/27/2019"",147700.0],[""02/26/2019"",153900.0]]}";

Then, you have a second series that is very similar...

string str2 = @"{""datapoints"":[[""02/28/2019"",145600.0],[""02/27/2019"",143600.0],[""02/26/2019"",152200.0]]}";

Note: the object arrays inside are both a length of "2", and both contain the same "date" as the [0] index.

How does one merge the 2 object arrays into 1, to yield the following output...

string str3 = @"{""datapoints"":[[""02/28/2019"",145600.0,145600.0],[""02/27/2019"",143600.0,143600.0],[""02/26/2019"",152200.0,152200.0]]}";

For clarity, I'm interested in using the [0] index once, and merging the [1] indexes together. (the number values)

Extra credit if this can be a loop, or can be done with any number of series.

1
  • I don't understand your merge logic - the values in your str3 don't correspond to the values in str1 or str2. For instance the first entries in str1 and str2 are ["02/28/2019",146800.0] and ["02/28/2019",145600.0] but your expected JSON has ["02/28/2019",145600.0,145600.0] which does not include 146800.0 at all. Is this a mistake in the question? Commented Mar 1, 2019 at 4:04

2 Answers 2

1

Using , you can deserialize each JSON sample to an object that contains a datapoints property that is an enumerable of object arrays, then merge them using the LINQ methods GroupBy() and Aggregate().

Say the JSON samples to be merged are in a string [][] jsonSeriesList like so:

string str1 = @"{""datapoints"":[[""02/28/2019"",146800.0],[""02/27/2019"",147700.0],[""02/26/2019"",153900.0]]}";
string str2 = @"{""datapoints"":[[""02/28/2019"",145600.0],[""02/27/2019"",143600.0],[""02/26/2019"",152200.0]]}";
var jsonSeriesList = new[] { str1, str2 }; // Add others as required

Then you can create a combined series as follows:

var merged = jsonSeriesList.Aggregate(
    new { datapoints = Enumerable.Empty<object[]>() },
    (m, j) => new
    {
        datapoints = m.datapoints.Concat(JsonConvert.DeserializeAnonymousType(j, m).datapoints)
            // Group them by the first array item.
            // This will throw an exception if any of the arrays are empty.
            .GroupBy(i => i[0])
            // And create a combined array consisting of the key (the first item from all the grouped arrays)
            // concatenated with all subsequent items in the grouped arrays.
            .Select(g => new[] { g.Key }.Concat(g.SelectMany(i => i.Skip(1))).ToArray())
    });

var mergedJson = JsonConvert.SerializeObject(merged);

Notes:

  • I am deserializing to an anonymous type for brevity. You could create an explicit data model if you prefer.

  • I am assuming the individual datapoint arrays all have at least one item.

  • There is no attempt to sort the resulting merged JSON by series date. You could do that if necessary.

  • The solution assumes that you will never have multiple component arrays in the same series with the same first item, e.g. "02/28/2019" repeated twice. If so, they will get merged also.

Sample .Net fiddle here.

Sign up to request clarification or add additional context in comments.

Comments

1

Here is a simplified example (simplified as validations might be required, but hope it given you a place to start):

  1. Convert it into dot net object
  2. Then go through each date point - for each date point go through all the series, adding the values.

//container object for the json series public class Container { public List<List<object>> datapoints; }

    //Input series in JSON 
    string[] inputSeries = new string[]
        {
            "{\"datapoints\": [[\"02/28/2019\", 146800.0],[\"02/27/2019\", 147700.0],[\"02/26/2019\", 153900.0]]}",
            "{\"datapoints\": [[\"02/28/2019\", 145600.0],[\"02/27/2019\", 143600.0],[\"02/26/2019\", 152200.0]]}"
        };

        //Container for input series in dot net object
        List<Container> con = new List<Container>();

        foreach (var series in inputSeries)
        {
            con.Add(JsonConvert.DeserializeObject<Container>(series));
        }

        // output container
        Container output = new Container();
        output.datapoints = new List<List<object>>();

        // assuming all series have equal number of data points.....might not be so
        for (int i = 0; i < con[0].datapoints.Count; i++)
        {
            output.datapoints.Add(new List<object>());
            // inner loop is to go across series for the same datapoint....
            for (int j = 0; j < con.Count; j++)
            {
                // add the date if this is the first series....after that only add the values
                // right now the assumption is that the dates are in order and match....validation logic might be required
                if (j == 0)
                {
                    output.datapoints[i].Add(con[j].datapoints[i][0]);
                    output.datapoints[i].Add(con[j].datapoints[i][1]);
                }
                else
                {
                    output.datapoints[i].Add(con[j].datapoints[i][1]);
                }
            }
        }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.