Reputation: 716
I want to compare two list of objects. These lists contains the same type of objects. I create a new List in my programme and i want to compare it at the old list which is in the database. I get it with a stored procedure, then i put it into an object.
The old list : the new list :
*Category 1* Category 5
*Category 2* Category 6
*Category 3* *Category 4*
Category 4
Here the aim is to delete the first three Category in the old list, beacause they don't exist in the new list. And to delete the Category 4 in the new list because category 4 already exists in the old list.
It is possible to use à method like Equals()
or use two foreach
loop to browse the lists ?
Thanks for you answers and advises
Upvotes: 1
Views: 8371
Reputation: 8693
It's not the most pretty of implementations but the fastest way you can do this is:
var tempA = new HashSet<int>(inputA.Select(item => item.Id));
var tempB = new HashSet<int>(inputB.Select(item => item.Id));
var resultA = new List<Category>(inputA.Count);
var resultB = new List<Category>(inputB.Count);
foreach (var value in inputA)
if (tempB.Contains(value.Id))
resultA.Add(value);
foreach (var value in inputB)
if (!tempA.Contains(value.Id))
resultB.Add(value);
resultA.TrimExcess();
resultB.TrimExcess();
// and if needed:
inputA = resultA;
inputB = resultB;
If you need more than item.id as unique then use a new Tuple such as:
inputA.Select(item => new Tuple<int, string>(item.Id, item.Title));
Another option is to override .GetHashCode in your category class such as:
public override int GetHashCode()
{
return Id.GetHashCode();
}
public override bool Equals(object obj)
{
var typedObj = obj as Category;
if (typedObj == null)
return false;
return Title == typedObj.Title && Id == typedObj.Id && Rank == typedObj.Rank;
}
Upvotes: 1
Reputation: 43300
You can use the linq, except
and where
var a = new List<string> { "a", "b", "c" };
var b = new List<string> { "c", "d", "e" };
var temp = a.Intersect(b).ToList();
b = b.Except(a).ToList();
a = temp;
Output:
a: "c"
b: "d", "e"
Note: It is probably more efficient to do this without linq
var a = new List<string> { "a", "b", "c" };
var b = new List<string> { "c", "d", "e" };
for(int i = 0; i < a.Count; i++)
if(b.Contains(a[i]))
b.Remove(a[i]);
else
a.Remove(a[i--]);
If you need to compare based on a particular value
for(int i = 0; i < a.Count; i++)
{
var obj = b.Where(item => item.Category == a[i].Category);
if(obj.Any())
b.Remove(obj.First());
else
a.Remove(a[i--]);
}
Upvotes: 4
Reputation: 34895
I would solve this by sorting the two list and iterating over the first and second list. I would compare the current item of the first list to the current item from the second. If a match is found I remove the match from the second list and I move to the next item in both lists, otherwise the current item of the first list is removed from it and the iteration continues in the first list.
Upvotes: 0