实际上my previous question让我思考
我意识到逆转Dictionary
并非易事。
什么是最优雅和可读的方式?
相同的情景学生多对多的班级
原始Dicitonary<int, List<int>>
,其中密钥为studentId,而值为List<int>
,其中包含classId并希望恢复为Dictionary<classId, List<studentId>>
由于
更新: 实际上我只是测试了Luke和Bruno的解决方案,并且他们返回了适当数量的分类,无论他们都拥有同一个学生,我会随着时间的推移进行更新。
答案 0 :(得分:46)
要反转字典很容易:
var newDic = oldDic.ToDictionary(x => x.Value, x => x.Key);
就是这样。
现在,你的问题不同了。它是关于扭转在字典上建立的多对多关系。
所以,假设你有Dictionary&lt; TEntity1,IEnumerable&lt; TEntity2&gt;&gt;。我们的想法是从中提取多对多关系的“中间表”。然后你可以在另一边重组它,然后重新转换成字典。
对于第一部分,我们将使用SelectMany的重载
“将序列的每个元素投影到 一个IEnumerable&lt; T&gt;, 将得到的序列展平成 一个序列,并调用一个结果 每个元素的选择器功能 在其中“
var table =
dict.SelectMany(
x => x.Value,
(dictEntry, entryElement) => new
{
Entity1 = dictEntry.Key,
Entity2 = entryElement
}
);
所以,现在你只需要按照你想要的方式重新组合这个表,然后将它转换成字典。
var newDict =
table
.GroupBy(x => x.Entity2,
x => x.Entity1,
(entity2, entity1) => new {entity1, entity2})
.ToDictionary(x => x.entity2, x => x.entity1);
答案 1 :(得分:8)
略有不同的方式(无论如何我的大脑更容易理解:) ...
var newDict = new Dictionary<int, List<int>>();
var dict = new Dictionary<int, List<int>>();
dict.Add( 1, new List<int>() { 1, 2, 3, 4, 5 } );
dict.Add( 2, new List<int>() { 1, 2, 3, 4, 5 } );
dict.Add( 3, new List<int>() { 1, 2, 6 } );
dict.Add( 4, new List<int>() { 1, 6, 7 } );
dict.Add( 5, new List<int>() { 8 } );
var newKeys = dict.Values.SelectMany( v => v ).Distinct();
foreach( var nk in newKeys )
{
var vals = dict.Keys.Where( k => dict[k].Contains(nk) );
newDict.Add( nk, vals.ToList() );
}
答案 2 :(得分:3)
我不确定这与your previous question的确切区别。
如果您只是询问如何返回Dictionary<int, List<int>>
而不是Dictionary<int, IEnumerable<int>>
,那么您只需要调用ToList
方法。
窃取和修改Mehrdad's answer to your other question:
var classToStudent = studentToClass
.SelectMany(
pair => pair.Value.Select(val => new { Key = val, Value = pair.Key }))
.GroupBy(item => item.Key)
.ToDictionary(gr => gr.Key, gr => gr.Select(item => item.Value).ToList());