Reputation: 23
Here is my problem:
I have two dictionaries with identical structures:
Dictionary<string, List<Object>> Existing
Dictionary<string, List<Object>> New
Basically what I need to do is to first find any List<Object>
that is in New but not in Existing based on the key and then find any Object in each List<Object>
contained in New that does not exist in its corresponding List<Object>
in Existing or is changed based on a number of properties in Object and, of course, the dictionary key.
I'm currently doing this by looping and checking each object individually, but I thought there must be a better way to do this using LINQ.
Hopefully that is clear, but let me know if you need further info.
Thanks.
Upvotes: 2
Views: 1761
Reputation: 13399
Dictionary<string, int> New = new Dictionary<string, int>();
Dictionary<string, int> Existing = new Dictionary<string, int>();
New.Add("A", 100);
New.Add("B", 200);
New.Add("Y", 300);
New.Add("X", 400);
Existing.Add("A", 1);
Existing.Add("B", 2);
Existing.Add("C", 3);
Existing.Add("D", 4);
Existing.Add("E", 5);
Existing.Add("F", 6);
Existing.Add("G", 7);
Existing.Add("H", 8);
var newStuff = New.Where(n => !Existing.ContainsKey(n.Key)).ToList();
var updatedStuff = Existing.Where(e => New.ContainsKey(e.Key) && e.Value != New.Single(n => n.Key == e.Key).Value);
newStuff.Dump();
updatedStuff.Dump();
//updated and new
newStuff.AddRange(updatedStuff);
newStuff.Dump();
Done in Linqpad.
Upvotes: 0
Reputation: 16121
As for new entries in the dictionary and new objects within an entry's List<object>
:
List<object>[] addedLists = New.Keys.Except(Existing.Keys)
.Select(key => New[key])
.ToArray();
object[] addedObjects = Existing.Keys.Intersect(New.Keys)
.SelectMany(key => New[key].Except(Existing[key])
.ToArray();
But the last requirement is a bit unclear. How would you define a changed object? Which objects should be compared for change? Comparing any object with any other object would potentially be defined as different, so there must be some similarities on which to base a comparison (e.g. the objects with the same value in their ID
property).
EDIT: As you clarified in your comment how object identity is defined, here's how to find all changed objects (assuming the dictionary's value is a list of Foo
that has a properties Name
and Type
that identify the object and property Value
that may change:
var differences = Existing.Keys.Intersect(New.Keys).SelectMany(key =>
from existingObj in Existing[key]
join newObj in New[key] on new { existingObj.Name, existingObj.Type } equals
new { newObj.Name, newObj.Type }
where existingObj.Value != newObj.Value
select new { Key = key, Existing = existingObj, New = newObj });
This will produce a sequence of objects each containing the key of the dictionary the difference was found in, the existing object and the new object. Identical objects will not be included in the results.
Upvotes: 3