我有一个类如下:
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);
但都给予假的。
检查标签列表是否相等的最快方法是什么?
更新
我正在寻找标签与书中标签完全相同的帖子。
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])”方法,并且此方法无法转换为存储表达式。
我该怎么解决这个问题?
4条答案
按热度按时间vkc1a9a21#
使用
SequenceEqual
检查序列相等性,因为Equals
方法检查 * 引用相等性 *。或者如果你不关心元素的顺序,使用
Enumerable.All
方法:第二个版本还需要对
Count
进行另一次检查,因为即使ints2
包含的元素比ints1
多,它也会返回true。所以更正确的版本应该是这样的:为了检查 * 不等式 *,只需反转
All
方法的结果:ykejflvf2#
List<T>
相等性不会逐个元素检查它们。你可以使用LINQ'sSequenceEqual
method来实现:要忽略顺序,请使用
SetEquals
:这应该可以工作,因为您正在比较不包含重复项的ID序列。如果是这样的话,你需要考虑到重复,在线性时间内完成的方法是组成一个基于哈希的计数字典,为第一个序列的每个元素加一个,为第二个序列的每个元素减一个,并检查结果计数是否全为零:
最后,如果您可以使用
O(N*LogN)
解决方案,则可以对两个序列进行排序,并使用SequenceEqual
比较它们是否相等。kqqjbcuj3#
wgeznvg74#
如果你想要相等的*值或相同序列中的对象,那么这些扩展可能对你有用: (相等的意思是值相等)*
对于包含值类型的列表:
对于包含引用类型的列表: