Reputation: 57
I am finding it hard to implement a logic which will check for if a certain key-value (together) in one file has an actual exactly similar key-value in another file
i have one file as below ,
[
{
"IdInOne": "001",
"NameInOne": "Name_2"
},
{
"IdInOne": "002",
"NameInOne": "Name_3"
}
]
and the other as
[
{
"IdInTwo": "001",
"NameInTwo": "Name_1"
},
{
"IdInTwo": "001",
"NameInTwo": "Name_2"
},
{
"IdInTwo": "001",
"NameInTwo": "Name_3"
},
{
"IdInTwo": "002",
"NameInTwo": "Name_4"
}
]
in this example there is one entry where "IdInOne": "001","NameInOne": "Name_2" matches an exactly same value in the second JSON file. So in that case I will print a success message
but there is no match in the second JSON file where "IdInOne": "002","NameInOne": "Name_3" hence I want to print in the Console an unsuccessful message
Can anyone help me on this please ? Any idea of what kinda algorithm I need ?
Upvotes: 1
Views: 74
Reputation: 26315
You could first make two model classes representing your JSON:
public class One
{
public string IdInOne { get; set; }
public string NameInOne { get; set; }
}
public class Two
{
public string IdInTwo { get; set; }
public string NameInTwo { get; set; }
}
Then deserialize the JSON with these classes using Newtonsoft Json.NET. Since we are dealing with JSON arrays, we can deserialize into List<T>
.
var json1 = "[{\"IdInOne\": \"001\",\"NameInOne\": \"Name_2\"},{\"IdInOne\": \"002\",\"NameInOne\": \"Name_3\"}]";
var json2 = "[{\"IdInTwo\": \"001\",\"NameInTwo\": \"Name_1\"},{\"IdInTwo\": \"001\",\"NameInTwo\": \"Name_2\"},{\"IdInTwo\": \"001\",\"NameInTwo\": \"Name_3\"},{\"IdInTwo\": \"002\",\"NameInTwo\": \"Name_4\"}]";
var deserializedJson1 = JsonConvert.DeserializeObject<List<One>>(json1);
var deserializedJson2 = JsonConvert.DeserializeObject<List<Two>>(json2);
Then you can simply compare using Any()
from LINQ:
foreach (var one in deserializedJson1)
{
if (deserializedJson2.Any(two => two.IdInTwo == one.IdInOne &&
two.NameInTwo == one.NameInOne))
{
Console.WriteLine($"Match found with {one.IdInOne} and {one.NameInOne}");
} else
{
Console.WriteLine($"No match found with {one.IdInOne} and {one.NameInOne}");
}
}
Which Outputs:
Match found with 001 and Name_2
No match found with 002 and Name_3
Another implementation could be to deserialize into tuples, then simply convert the twos to a HashSet<T>
and use it for lookups. Having a hashset improves the lookups from O(N) to O(1), and could provide a performance increase for larger sets of data. HashSet<T>.Contains(T)
is a O(1) method.
var ones = JsonConvert
.DeserializeObject<List<One>>(json1)
.Select(x => (x.IdInOne, x.NameInOne));
var lookups = JsonConvert
.DeserializeObject<List<Two>>(json2)
.Select(x => (x.IdInTwo, x.NameInTwo))
.ToHashSet();
foreach (var (IdInOne, NameInOne) in ones)
{
if (lookups.Contains((IdInOne, NameInOne)))
{
Console.WriteLine($"Match found with {IdInOne} and {NameInOne}");
} else
{
Console.WriteLine($"No match found with {IdInOne} and {NameInOne}");
}
}
Upvotes: 1
Reputation: 4119
Use Newtonsoft and use a POCO class to parse your two models and compare after that both instances properties.
See this example of how to deserialize a json
https://www.newtonsoft.com/json/help/html/DeserializeObject.htm
You can use reflection to iterate for all the properties on the second object asking for the value of the property to compare. This is useful when you don't know the name of the property to compare with.
Hope this helps
Upvotes: 0