Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/327.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# LINQ分组到多个组_C#_Linq - Fatal编程技术网

C# LINQ分组到多个组

C# LINQ分组到多个组,c#,linq,C#,Linq,我有以下数据 IEnumerable<Tuple<T, List<U>>> Data; IEnumerable数据; 或者也可以表示为 Dictionary<T, List<U>> GroupedA 字典组a 它可能属于一个或多个U。我想要 将其反转,以便查找U并找到所有相关的 T在结构中 Dictionary<U, List<T>> GroupedB; 字典组b; 试图想出一个简洁的LINQ表达式来

我有以下数据

IEnumerable<Tuple<T, List<U>>> Data;
IEnumerable数据;
或者也可以表示为

Dictionary<T, List<U>> GroupedA
字典组a
它可能属于一个或多个U。我想要 将其反转,以便查找U并找到所有相关的 T在结构中

Dictionary<U, List<T>> GroupedB;
字典组b;
试图想出一个简洁的LINQ表达式来颠倒字典

编辑

事实上,下面的正确答案表明我真正想要的是

ILookup<U, T>
ILookup
而不是

Dictionary<U, List<T>>
字典
试试这个:

Data.SelectMany(tuple => tuple.Item2.Select(u => new { U = u, T = tuple.Item1 }))
    .GroupBy(x => x.U)
    .ToDictionary(g => g.Key, g => g.Select(x => x.T).ToList());
完整的测试用例代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xunit;
using FluentAssertions;

namespace StackOverflow
{
    public class Class1
    {
        //Populating data
        Dictionary<int, List<string>> GroupedA = new Dictionary<int, List<string>>();

        public Class1()
        {
            GroupedA.Add(1, new List<string> { "1", "2", "3" });
            GroupedA.Add(2, new List<string> { "1", "32", "3", "4" });
            GroupedA.Add(3, new List<string> { "1", "52", "43", "4" });
        }

        [Fact]
        public void ToDictionarySpec()
        {
            var data = GroupedA.Select(v => Tuple.Create(v.Key, v.Value));

            var r = data.SelectMany(tuple => tuple.Item2.Select(u => new { U = u, T = tuple.Item1 }))
            .GroupBy(x => x.U)
            .ToDictionary(g => g.Key, g => g.Select(x => x.T).ToList());

            //Printing data 
            var pairs = r.Select(pair => string.Format("{0} : {1}", pair.Key, string.Join(",", pair.Value)));
            Console.WriteLine(string.Join(Environment.NewLine, pairs));
        }


    }
}

IEnumerable接口只能有一个泛型类型参数。数据的实际类型是什么?我的坏消息。抱歉,它应该是一个可枚举的元组。我认为最后的类型将只是
字典
而不是
字典
GroupBy将只允许成员成为一个组的一部分:)。关键问题是一个项目可以属于多个组。@bradgonesurfing:对不起,我不理解那个评论。你测试过新版本吗?想想
字典
字典
这是一种多对多的关系,我想把它颠倒过来。@bradgonesurfing:我明白了。再说一遍:你测试过了吗?托卢库普是关键。对于那些希望理解的人,我发现了一篇关于ToLookup和ToDictionary之间区别的博文。你的问题明确要求提供一本
词典
ToLookup
没有提供这一点。@DanielHilgarth,对不起,我使用了OPs单词
我想将其倒置,这样我可以查找U,并在结构中找到所有相关的t作为问题陈述,这可以通过使用
ILookup
完美实现。如果我做了坏事,对不起。@IlyaIvanov:我不反对你的回答。这很好。我反对老年退休金计划对你和我的回答的评论。OP显然对LINQ的理解有限,他说
ToDictionary
是一种错误的使用方法。我认为Daniel的方法是正确的,因为他是第一个,但要感谢各种技术。
Test Name:  ToDictionarySpec
Test Outcome:   Passed
Result StandardOutput:  
1 : 1,2,3
2 : 1
3 : 1,2
32 : 2
4 : 2,3
52 : 3
43 : 3
//Populating data
Dictionary<int, List<string>> GroupedA = new Dictionary<int, List<string>>();

GroupedA.Add(1, new List<string>{"1","2","3"});
GroupedA.Add(2, new List<string>{"1","32","3","4"});
GroupedA.Add(3, new List<string>{"1","52","43","4"});


//Inverting data
ILookup<string, int> GroupedB = 
       GroupedA.SelectMany(pair => pair.Value.Select(val => new{pair.Key, val}))
               .ToLookup(pair => pair.val, pair => pair.Key);



//Printing data 
var pairs = GroupedB.Select(pair => string.Format("{0} : {1}", pair.Key, string.Join(",", pair)));

Console.WriteLine (string.Join(Environment.NewLine, pairs));
1 : 1,2,3 
2 : 1 
3 : 1,2 
32 : 2 
4 : 2,3 
52 : 3 
43 : 3