2014-09-19 140 views
1

我想比较两个对象列表。这些列表包含相同类型的对象。我在我的程序中创建一个新的列表,我想在数据库中的旧列表中进行比较。我用存储过程得到它,然后把它放到一个对象中。比较两个对象列表C#

The old list :      the new list : 

*Category 1*       Category 5 
*Category 2*       Category 6 
*Category 3*       *Category 4* 
Category 4 

这里的目的是删除前三个类别中的旧列表,东阳他们不会在新的列表中存在。并且为了删除新列表中的类别4,因为类别4已经存在于旧列表中。

可以使用类似Equals()的à方法或使用两个foreach循环来浏览列表?

感谢您的答案和建议

+0

你试过'.Except()'扩展方法吗? – 2014-09-19 08:55:38

+0

我试过,但是,问题是我不使用对象的所有属性,它不工作。可以选择要比较的属性? – Julien698 2014-09-19 09:06:20

+1

Except()方法可以采用必须实现的IEqualityComparer(http://msdn.microsoft.com/zh-cn/library/vstudio/ms132151%28v=vs.100%29.aspx)。它应该执行你想要的比较。 – 2014-09-19 09:09:56

回答

3

您可以使用LINQ,exceptwhere

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; 

输出:

a: "c" 
b: "d", "e" 

注:这可能是更有效的,如果你这样做没有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--]); 

需要根据特定值

01进行比较
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--]); 
} 
+2

你可以使用'Intersect'而不是'Where' /'Contains'组合。例如:'var temp = a.Intersect(b).ToList();' – LukeH 2014-09-19 09:09:22

+0

@LukeH - 谢谢,我忘了'Intersect' – Sayse 2014-09-19 09:10:34

+0

这是一个好主意,它工作正常,但我有anonther问题,它的对象属性不一样。例如,我的Title = Category1,Id = 2,rank = 4,另一个Title = Category1,Id = 2,rank = 0.因为Rank不匹配。我认为我会解决排名问题,一直把它归为零! – Julien698 2014-09-19 09:29:06

0

我会通过排序两个列表,并遍历第一和第二列表解决这个问题。我会将第一个列表的当前项目与第二个当前项目进行比较。如果找到匹配项,我从第二个列表中删除匹配项,然后移动到两个列表中的下一个项目,否则将删除第一个列表中的当前项目,迭代继续在第一个列表中。

+0

是什么让你觉得他们可以排序? – Rawling 2014-09-19 09:02:08

1

它不是最漂亮的实现,但你可以做到这一点的最快方法是:

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; 

如果您需要超过item.id独特然后用一个新的记录,如:

inputA.Select(item => new Tuple<int, string>(item.Id, item.Title)); 

另一种选择是在你的类类重写.GetHashCode如:

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; 
}