C# 检查两个列表是否相等
我的课程如下:C# 检查两个列表是否相等,c#,linq,C#,Linq,我的课程如下: public class Tag { public Int32 Id { get; set; } public String Name { get; set; } } 我有两个标签列表: List<Tag> tags1; List<Tag> tags2; 但两者都给我错误的答案 检查标签列表是否相等的最快方法是什么 更新 我要找的职位标签是完全一样的标签在一本书 IRepository repository = new Reposito
public class Tag {
public Int32 Id { get; set; }
public String Name { get; set; }
}
我有两个标签列表:
List<Tag> tags1;
List<Tag> tags2;
但两者都给我错误的答案
检查标签列表是否相等的最快方法是什么
更新
我要找的职位标签是完全一样的标签在一本书
IRepository repository = new Repository(new Context());
IList<Tags> tags = new List<Tag> { new Tag { Id = 1 }, new Tag { Id = 2 } };
Book book = new Book { Tags = new List<Tag> { new Tag { Id = 1 }, new Tag { Id = 2 } } };
var posts = repository
.Include<Post>(x => x.Tags)
.Where(x => new HashSet<Int32>(tags.Select(y => y.Id)).SetEquals(book.Tags.Select(y => y.Id)))
.ToList();
IRepository repository=new repository(new Context());
IList tags=new List{new Tag{Id=1},new Tag{Id=2};
Book Book=newbook{Tags=newlist{newtag{Id=1},newtag{Id=2}};
var posts=存储库
.Include(x=>x.Tags)
.Where(x=>newhashset(tags.Select(y=>y.Id)).SetEquals(book.tags.Select(y=>y.Id)))
.ToList();
我正在使用,我得到错误信息:
mscorlib.dll中发生“System.NotSupportedException”类型的异常,但未在用户代码中处理
其他信息:LINQ to Entities无法识别方法“Boolean SetEquals(System.Collections.Generic.IEnumerable`1[System.Int32])”方法,并且此方法无法转换为存储表达式
如何解决此问题?列表
等式不会逐个元素检查它们。您可以使用:
var a = ints1.SequenceEqual(ints2);
要忽略顺序,请使用SetEquals
:
var a = new HashSet<int>(ints1).SetEquals(ints2);
最后,如果您对O(N*LogN)
解决方案满意,您可以对两个序列进行排序,并使用SequenceEqual
检查序列相等性,因为Equals
方法检查引用相等性
或者,如果您不关心元素顺序,请使用方法:
第二个版本还需要再次检查Count
,因为即使ints2
包含的元素比ints1
多,它也会返回true。所以更正确的版本应该是这样的:
var a = ints1.All(ints2.Contains) && ints1.Count == ints2.Count;
要检查不等式,只需反转All
方法的结果:
var a = !ints1.All(ints2.Contains)
使用
SequenceEqual
时,元素必须以相同的顺序排列-OP希望元素以任何顺序排列。@DStanley你说得对,我一开始就忽略了这一点。现在应该没事了。@TimSchmelter编辑就是为了这个。编辑后情况如何?@dasblinkenlight仍然无法工作,如果其中任何一个序列包含重复项-{1,1,2,3}
将“等于”{1,2,2,3}
@dasblinkenlight肯定可以。事实上,OP的exmaple中的第五个序列是这样的。你说的不相等是什么意思?你是说所有元素都应该不同,还是说它们不应该包含相同的元素,至少应该有一个不同的元素?你的序列ids5
包含重复项。这是故意的吗?@Selman22我的意思是这两个列表应该包含完全相同的元素。。。该命令不适用matter@dasblinkenlight是的,因为在本例中ID是唯一的,因为它们是主键。您可能希望单独发布更新后的问题,因为编辑后,问题的解决方案将与迄今为止发布的任何问题完全不同。添加[EF]
标记,并确保新问题的标题是“在EF的Where子句中比较列表”或类似的内容。lambda参数的名称很奇怪。它们不是列表,它们是元素。我要么在OP的上下文中使用id
,要么在一般上下文中使用element
。这家伙显然是从其他地方复制了这个答案,因为从参数名称判断,他甚至不知道它是做什么的。我想它正好涵盖了手头的问题。它比较两个列表,无论顺序如何。速度慢,不处理重复的列表<代码>[1,1,2]!=[1,2,2]@code根据OP在问题中的评论,duplicates不重要注意:您可能习惯于将.All
与类似的lambda一起使用。All(i=>ints2.Contains(i))
,但是由于list.Contains()与接受int
并返回bool>的函数签名相匹配,然后,他直接将函数名作为谓词传递。本质上与ints1.All(i=>ints2.Contains(i))
相同。我只是想指出这一点,以防像我这样的其他人最初感到困惑。我会将var a=ints1.All(ints2.Contains)&&ints1.Count==ints2.Count代码>到变量a=ints1.Count==ints2.Count&&ints1.All(ints2.Contains)代码>。简单的计数比较可能比.All
调用快得多。如果计数不相等,它将返回得更快。我将对这个答案进行向下投票,因为这并不适用于所有情况,列表A{A,A}和列表B包含{B,A}现在是ListB.all(listA.contains)和listA.all(ListB.contains)将给出不同的结果,因为两者都有相同的计数,即使两者不同,我们也会在其中一种情况下得到正确的结果,如果一个列表有多个条目,它将不起作用-
var counts = ints1
.GroupBy(v => v)
.ToDictionary(g => g.Key, g => g.Count());
var ok = true;
foreach (var n in ints2) {
int c;
if (counts.TryGetValue(n, out c)) {
counts[n] = c-1;
} else {
ok = false;
break;
}
}
var res = ok && counts.Values.All(c => c == 0);
var a = ints1.SequenceEqual(ints2);
var a = ints1.All(ints2.Contains);
var a = ints1.All(ints2.Contains) && ints1.Count == ints2.Count;
var a = !ints1.All(ints2.Contains)
Enumerable.SequenceEqual(FirstList.OrderBy(fElement => fElement),
SecondList.OrderBy(sElement => sElement))