public static bool SequenceEqualsIgnoreOrder<T>(this IEnumerable<T> list1, IEnumerable<T> list2, IEqualityComparer<T> comparer = null)
{
if(list1 is ICollection<T> ilist1 && list2 is ICollection<T> ilist2 && ilist1.Count != ilist2.Count)
return false;
if (comparer == null)
comparer = EqualityComparer<T>.Default;
var itemCounts = new Dictionary<T, int>(comparer);
foreach (T s in list1)
{
if (itemCounts.ContainsKey(s))
{
itemCounts[s]++;
}
else
{
itemCounts.Add(s, 1);
}
}
foreach (T s in list2)
{
if (itemCounts.ContainsKey(s))
{
itemCounts[s]--;
}
else
{
return false;
}
}
return itemCounts.Values.All(c => c == 0);
}
用法:
var list1 = new List<int> { 1, 2, 3, 1 };
var list2 = new List<int> { 2, 1, 3, 2 };
bool sameItemsIgnoringOrder = list1.SequenceEqualsIgnoreOrder(list2);
// false because same count and same items but 1 appaears twice in list1 but once in list2
public static bool CompareList(this List<string> _initialList, List<string> _secondaryList)
{
var set = new HashSet<string>(_initialList);
var equals = set.SetEquals(_secondaryList);
return equals ? _initialList.Count() == _secondaryList.Count() : false;
}
这样,您将使用集合检查列表中的两个元素,而且元素计数有助于您检查注解中给出的示例,如***{0,1,1} vs {0,1}*** 此外,通过扩展,您可以在代码中多次调用它。您可以修改它以与潜在的null进行比较。
public static bool CompareList(this List<string> _initialList, List<string>? _secondaryList)
{
//test if _secondaryList is null while initial is not
if (_secondaryList == null) return false;
var set = new HashSet<string>(_initialList);
var equals = set.SetEquals(_secondaryList);
return equals ? _initialList.Count() == _secondaryList.Count() : false;
}
6条答案
按热度按时间bfhwhh0e1#
这就是集合(例如
HashSet<T>
)的作用,集合没有定义的顺序,SetEquals
验证集合和另一个集合是否包含相同的元素。lb3vh1jj2#
您可以使用
!Except
+Any
:这不是检查两者是否具有相同的项,而是检查list1是否包含在list2中(忽略重复项)。
如果要了解
list2
是否包含在list1
中,请使用:因此,如果要确保两个列表包含相同的项,就必须同时进行这两项检查。
如果你还想考虑到两个列表的大小是一样的,可以使用
list1.Count==list2.Count
进行预检查,但是如果你使用set方法(参见Harald's comment),这个检查就没有用了,如果你忽略了重复项,比较计数就没有多大意义了。一般来说,
HashSet<T>
有一些很好的和有效的方法来检查两个序列是否有相同的项(忽略重复项),dcastro already showed是一个。如果您想要一个有效的解决方案来确定两个列表是否包含相同的项,相同的计数和不忽略重复项但忽略顺序(否则使用
SequenceEquals
):用法:
如果顺序很重要并且重复项也很重要,请使用:
vsikbqxv3#
不使用linq。
q0qdq0h24#
对有序列表使用SequenceEqual-例如
8yparm6h5#
这是旧的,但我会修改由dcastro的答案,并在extension构建:
这样,您将使用集合检查列表中的两个元素,而且元素计数有助于您检查注解中给出的示例,如***{0,1,1} vs {0,1}***
此外,通过扩展,您可以在代码中多次调用它。您可以修改它以与潜在的
null
进行比较。jckbn6z76#
您可以尝试Except
Except
返回first中未出现在second中的元素