我想拍一个Dictionary<string, List<int>>
然后为字典中的所有重复列表创建组。
Dictionary<string, List<int>> AllLists = new Dictionary<string, List<int>>()
{
{"one", new List<int>() {1, 2, 3, 4, 5}},
{"two", new List<int>() {1, 2, 3, 4, 5}},
{"three", new List<int>() {1, 1, 1, 1, 1}}
};
var ListGroups = AllLists.GroupBy(p => p.Value);
这应该将具有匹配列表的字典索引分组到它们自己的组中,但它只是为字典中的每个索引创建一个组。我做错了什么?
最佳答案
这将对您的 List<int>
使用引用比较对象。由于两者 List<int>
包含 [1, 2, 3, 4, 5]
分别实例化,它们将具有不同的引用。
例如,尝试以下操作:
var ListGroups = AllLists.GroupBy(p => string.Join(",", p.Value));
这将按 string
分组你的列表的表示。请注意,这可能不是您想要做的并且纯粹是说明性的。
您可以使用 this overload的 GroupBy
传递自定义的方法 IEqualityComparer<List<int>>
实际上使用 Enumerable.SequenceEqual
查看列表的内容.
这是 IEqualityComparer<IEnumerable<T>>
:
class IEnumerableEqualityComparer<T> : IEqualityComparer<IEnumerable<T>>
{
public bool Equals(IEnumerable<T> a, IEnumerable<T> b)
{
return Enumerable.SequenceEqual(a, b);
}
public int GetHashCode(IEnumerable<T> source)
{
if (source == null)
{
return 0;
}
int shift = 0;
int result = 1;
foreach (var item in source)
{
int hash = item != null ? item.GetHashCode() : 17;
result ^= (hash << shift)
| (hash >> (32 - shift))
& (1 << shift - 1);
shift = (shift + 1) % 32;
}
return result;
}
}
下面是你如何使用它:
var ListGroups = AllLists.GroupBy(p => p.Value,
new IEnumerableEqualityComparer<int>());
请注意,因为 IEqualityComparer<T>
在 T
中是逆变的您可以将上面的用于 List<int>
因为那实现了 IEnumerable<int>
.
关于c# - 如何在列表相同的 Dictionary<string, List<int>> 中按 List<int> 分组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22541330/