我有一个课程如下:
public class Tag {
public Int32 Id { get; set; }
public String Name { get; set; }
}
我有两个标签列表:
List<Tag> tags1;
List<Tag> tags2;
我使用LINQ的select来获取每个标签列表的ID。然后:
List<Int32> ids1 = new List<Int32> { 1, 2, 3, 4 };
List<Int32> ids2 = new List<Int32> { 1, 2, 3, 4 };
List<Int32> ids3 = new List<Int32> { 2, 1, 3, 4 };
List<Int32> ids4 = new List<Int32> { 1, 2, 3, 5 };
List<Int32> ids5 = new List<Int32> { 1, 1, 3, 4 };
ids1应该等于ids2和ids3 ......两者都有相同的数字。
ids1不应该等于ids4和ids5 ......
我尝试了以下内容:
var a = ints1.Equals(ints2);
var b = ints1.Equals(ints3);
但两人都给我假。
检查标签列表是否相同的最快方法是什么?
更新
我正在寻找TAGS与BOOK中的TAGS完全相同的帖子。
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();
我正在使用Entity Framework并收到错误:
mscorlib.dll中发生了'System.NotSupportedException'类型的异常,但未在用户代码中处理
附加信息:LINQ to Entities无法识别方法'Boolean SetEquals(System.Collections.Generic.IEnumerable`1 [System.Int32])'方法,并且此方法无法转换为商店表达式。
我该如何解决这个问题?
答案 0 :(得分:245)
使用SequenceEqual
检查序列是否相等,因为Equals
方法检查引用相等。
var a = ints1.SequenceEqual(ints2);
或者,如果您不关心元素顺序,请使用Enumerable.All
方法:
var a = ints1.All(ints2.Contains);
第二个版本还需要对Count
进行另一次检查,因为即使ints2
包含的元素多于ints1
,它也会返回true。所以更正确的版本是这样的:
var a = ints1.All(ints2.Contains) && ints1.Count == ints2.Count;
为了检查不等式,只需反转All
方法的结果:
var a = !ints1.All(ints2.Contains)
答案 1 :(得分:102)
List<T>
等式不会逐元素地检查它们。您可以使用LINQ's SequenceEqual
method:
var a = ints1.SequenceEqual(ints2);
要忽略订单,请使用SetEquals
:
var a = new HashSet<int>(ints1).SetEquals(ints2);
这应该有效,因为您正在比较不包含重复项的ID序列。如果确实如此,并且你需要考虑重复,那么在线性时间内完成它的方法是组成一个基于哈希的计数字典,为第一个序列的每个元素添加一个,为第二个序列的每个元素减去一个序列,并检查结果计数是否都为零:
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);
最后,如果您对O(N*LogN)
解决方案没问题,可以对这两个序列进行排序,并使用SequenceEqual
对它们进行相等性比较。
答案 2 :(得分:23)
Enumerable.SequenceEqual(FirstList.OrderBy(fElement => fElement),
SecondList.OrderBy(sElement => sElement))