部分取消组合重复值列表

Bob*_*son 7 c# linq

我知道如何使用LINQ对数据进行分组,我知道如何将其拆分为单独的项目,但我不知道如何仅将其部分取消组合.

我有一组看起来像这样的数据:

var data = new Dictionary<Header, Detail>()
{
    { new Header(), new Detail { Parts = new List<string> { "Part1", "Part1", "Part2" } } }
};
Run Code Online (Sandbox Code Playgroud)

为了正确处理这个问题,我需要复制部分的每个实例都是字典中的单独条目(尽管如果它仍然是字典并不重要 - IEnumerable<KeyValuePair<Header, Detail>>完全可以接受).但是,我不想Parts完全拆分列表 - 在列表中有不同的部分是可以的.

具体来说,我希望最终数据看起来像这样:

{
  { new Header(), new Detail { Parts = new List<string> { "Part1", "Part2" } } },
  { new Header(), new Detail { Parts = new List<string> { "Part1" } } },
}
Run Code Online (Sandbox Code Playgroud)

对于更复杂的示例:

var data = new Dictionary<Header, Detail>()
{
    { new Header(1), new Detail { Parts = new List<string> { "Part1", "Part1", "Part2" } } },

    { new Header(2), new Detail { Parts = new List<string> { "Part1", "Part2" } } },

    { new Header(3), new Detail { Parts = new List<string> { "Part1", "Part2", "Part2", "Part2", "Part3", "Part3"} } }
};

var desiredOutput = new List<KeyValuePair<Header, Detail>>()
{
    { new Header(1), new Detail { Parts = new List<string> { "Part1", "Part2" } } },
    { new Header(1), new Detail { Parts = new List<string> { "Part1" } } },

    { new Header(2), new Detail { Parts = new List<string> { "Part1", "Part2" } } },

    { new Header(3), new Detail { Parts = new List<string> { "Part1", "Part2", "Part 3" } } },
    { new Header(3), new Detail { Parts = new List<string> { "Part2", "Part3" } } },
    { new Header(3), new Detail { Parts = new List<string> { "Part2" } } }
};
Run Code Online (Sandbox Code Playgroud)

有什么建议?

Ser*_*kiy 2

Linq 在这里不会给你太多帮助,但这里有一个扩展方法,它可以解决这个问题:

public static IEnumerable<KeyValuePair<Header, Detail>> UngroupParts(
    this IEnumerable<KeyValuePair<Header, Detail>> data)
{
    foreach (var kvp in data)
    {
        Header header = kvp.Key;
        List<string> parts = kvp.Value.Parts.ToList();
        do
        {
            List<string> distinctParts = parts.Distinct().ToList();
            Detail detail = new Detail() { Parts = distinctParts };
            yield return new KeyValuePair<Header, Detail>(header, detail);

            foreach (var part in distinctParts)
                parts.Remove(part);
        }
        while (parts.Any());
    }
}
Run Code Online (Sandbox Code Playgroud)

用法:

var desiredOutput = data.UngroupParts();
Run Code Online (Sandbox Code Playgroud)