繁体   English   中英

LINQ分组到多个组

[英]LINQ grouping to more than one group

我有以下数据

IEnumerable<Tuple<T, List<U>>> Data;

或者也可以表达为

Dictionary<T, List<U>> GroupedA

给出一个T它可能属于一个或多个U.我想反转这个,所以我可以查找U并找到结构中所有相关的T

Dictionary<U, List<T>> GroupedB;

试着想出一个简洁的LINQ表达式来反转字典。

编辑

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

ILookup<U, T>

而不是

Dictionary<U, List<T>>
//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 

尝试这个:

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));
        }


    }
}

输出

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM