反转多对多字典<键,列表<值>>

rou*_*sis 23 c# dictionary

实际上我之前的问题让我思考,我意识到逆转一个Dictionary并不是微不足道的.什么是最优雅和可读的方式呢?

同样的情景学生多对多与班级

Dicitonary<int, List<int>>key是studentId的原始值,Value是List<int>包含classId并想要恢复的值Dictionary<classId, List<studentId>>

谢谢

更新:实际上我只是测试了Luke和Bruno的解决方案,并且他们返回了适当数量的分类,无论他们都拥有相同的学生,我会随着时间的推移进行更新.

Bru*_*eis 46

反转字典很容易:

var newDic = oldDic.ToDictionary(x => x.Value, x => x.Key);
Run Code Online (Sandbox Code Playgroud)

就这样.

现在,你的问题是不同的.它是关于扭转在字典上建立的多对多关系.

所以,假设你有Dictionary <TEntity1,IEnumerable <TEntity2 >>.我们的想法是从中提取多对多关系的"中间表".然后你可以在另一边重组它,然后重新转换成字典.

对于第一部分,我们将使用SelectMany的重载

"将序列的每个元素投影到IEnumerable <T>,将生成的序列展平为一个序列,并在其中的每个元素上调用结果选择器函数."

var table =
    dict.SelectMany(
        x => x.Value,
        (dictEntry, entryElement) => new
               {
                      Entity1 = dictEntry.Key,
                      Entity2 = entryElement
               }
    );
Run Code Online (Sandbox Code Playgroud)

所以,现在你只需要按照你想要的方式重新组合这个表,然后将它转换为字典.

 var newDict =
     table
         .GroupBy(x => x.Entity2,
                  x => x.Entity1,
                  (entity2, entity1) => new {entity1, entity2})
         .ToDictionary(x => x.entity2, x => x.entity1);
Run Code Online (Sandbox Code Playgroud)

  • 这样做的问题是您必须确保值是唯一的 (3认同)
  • 同行压力徽章! (3认同)
  • 通过给出主题标题最合乎逻辑的答案,你完全没有回答里面问题的内容.有趣. (3认同)

JP *_*oto 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() );
}
Run Code Online (Sandbox Code Playgroud)