我想获取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);
这应该将具有匹配列表的字典索引分组到它们自己的组中,但它只是为字典中的每个索引创建一个组。我做错了什么?
答案 0 :(得分:6)
您将在List<int>
个对象上使用参考比较。由于包含List<int>
的{{1}}都是单独实例化的,因此它们将具有不同的引用。
尝试以下方法,例如:
[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>
。