简体   繁体   中英

Efficient way to Merge two objects in C#

I have two objects in c#. One is for Header details (Dictionary) and other is for transaction. Both comes from different systems.

First Object - (of type NameValueCollection or any object where such mapping is present)

    Name: "NameOfA"
    Value : "A1"  //Name of the property in second object

    Name: : "NameOfB"
    Value: "B1"  //Name of the property in second object

    Name: : "NameOfC"
    Value: "C1"  //Name of the property in second object

    Name: : "NameOfD"
    Value: "D1"  //Name of the property in second object

Second Object (Custom type / JObject) -

    "Property 1" : "Property 1 Value",
    "Property 2" : "Property 2 Value",
    "Property 3" : "Property 3 Value",
    "Property 4:  {
        [
            {
                "A1" : "Value of A1", //The key "A1" here maps to the value property of First object
                "Other Property 1" : "Value of other property 1",
                "Other Property 2" : "Value of other property 2",
                "Other Property 3" : 100
            },
            
            {
                "B1" : "Value of B1",
                "Other Property 1" : "Value of other property 1",
                "Other Property 2" : "Value of other property 2",
                "Other Property 3" : 100
            },

            {
                "C1" : "Value of C1",
                "Other Property 1" : "Value of other property 1",
                "Other Property 2" : "Value of other property 2",
                "Other Property 3" : 100
            },
            {
                "D1" : 100; // Value of D1
                "Other Property 1" : "Value of other property 1",
                "Other Property 2" : "Value of other property 2",
                "Other Property 3" : 100
            },
                
        ]
    
    }

The relation between two object is, the value of First object is a Key in Second object (In a sub array).

eg - The Value: "A1" , This value "A1" of first object is key in second object:

"Property 4:  {
        [
            {
                *"A1"* : "Value of A1": 

I want to process these two objects together, so i can get following format:

[
        {
            "NameOfTask": "NameOfA",   // Name property of first object
            "ValueOfTask": "Value of A1" //Value of Property A1 in second object
        },

        {
            "NameOfTask": "NameOfB",
            "ValueOfTask": "Value of B1"
        },

        {
            "NameOfTask": "NameOfC",
            "ValueOfTask": "Value of C1"
        },

        {
            "NameOfTask": "NameOfD",
            "ValueOfTask": 100
        }


    ]

What could be the fastest algorithm to process such two different object as the object structure is totally custom and in my First object There could be 100 records and in second there could be 1000.

Thanks in advance.

You can use a Dictionary<> to temporarily store a mapping between the two objects. If the First Object is smaller than the Second Object, I would recommend, storing the First Object's information. Otherwise, do it the other way around.

For reasons of clarity, here is how I set up the two objects:

var firstObject = new NameValueCollection();
firstObject.Add("NameOfA", "A1");
firstObject.Add("NameOfB", "B1");
firstObject.Add("NameOfC", "C1");
firstObject.Add("NameOfD", "D1");

var secondObject = JObject.ReadFrom(tr); // tr contains your JSON

Now let's build the intermediate structure. Although NameValueCollection allows to store multiple values per key, I assume that you only use the first entry. We need to be able to look up the name by value for the second step. So, we build this dictionary:

var keyToName = new Dictionary<string, string>();
for (int i = 0; i < firstObject.Count; ++i )
{
    keyToName.Add(firstObject.GetValues(i)[0], firstObject.GetKey(i));
}

Then we need to extract all properties from the Second Object. I do this recursively using this function:

void ProcessToken(JToken json, Dictionary<string, string> keyToName, NameValueCollection firstObject)
{
    if (json.Type == JTokenType.Property)
    {
        var prop = (JProperty)json;
        // update firstObject here
    }


    foreach (var item in json.Children())
    {
        ProcessToken(item, keyToName, firstObject);
    }
}

The actual update of the first object has to be placed at the line of the comment. There, we need to check if we have an entry corresponding to the property. And if we do, update it:

var hasKey = keyToName.TryGetValue(prop.Name, out string key);
if(hasKey)       
{
    // replace value
    firstObject.Remove(key);
    firstObject.Add(key, prop.Value.ToString());
}

And that's it. Here is some demo output:

Collection before processing:
NameOfA: A1
NameOfB: B1
NameOfC: C1
NameOfD: D1

Collection after processing:
NameOfA: Value of A1
NameOfB: Value of B1
NameOfC: Value of C1
NameOfD: 100;

If you need the final result in another data structure, feel free to adapt the code. The core principle is always the same.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM