如何使用Linq对包含集合的集合进行去规范化

5
我将尝试转换下面的集合:
源代码:
"a", "b", {1,2,3}
"d", "f", {1,2,2}
"y", "z", {}

目的地

"a", "b", 1
"a", "b", 2
"a", "b", 3
"d", "f", 1
"d", "f", 2
"d", "f", 2
"y", "z", null

我已经研究过它,认为答案在SelectMany()方法中,但我似乎无法确定答案。
问题类似于:如何使用LINQ选择集合内的集合?,它使集合非规范化,但它没有显示如何包括相关的列(例如我的示例中的第1和第2列)。
不同之处在于,我需要包括前两列,并返回一个没有集合条目的行。

3
展示一些代码。这些集合的类型是什么?类似于IEnumerable<Tuple<string,string,IEnumerable<int>>>这样的吗? - Henrik
@Henrik 抱歉,我应该提供一些代码。我不经常发布帖子,但我会记住这一点,以便在未来的帖子中更清楚地表达我的问题。顺便说一下,你的猜测是正确的! - dubs
3个回答

2
使用元组列表作为示例:
var source = new List<Tuple<string, string, int[]>> {
    Tuple.Create("a", "b", new int[] {1,2,3}),
    Tuple.Create("d", "f", new int[] {1,2,2}),
    Tuple.Create("y", "z", new int[0])
};


var destination =
from t in source
from i in t.Item3.Select(x => (int?)x).DefaultIfEmpty()
select Tuple.Create(t.Item1, t.Item2, i);

一针见血!谢谢。 - dubs

2
假设有一些适合于 SourceDestination 元素的合适类型 SrcDst。然后,类似于文档中的示例,可以使用以下语句解决该任务。
Dest = Source.SelectMany(
    iSrc => iSrc.Third,
    (iSrc,No) => new Dest(){ First = iSrc.First,
                             Second = iSrc.Second,
                             Third = No
                           }
);

0

检查可能的解决方案之一:

var source = new List<Tuple<string, string, int[]>>{
        new Tuple<string,string,int[]>("a", "b", new int[]{1,2,3}),
        new Tuple<string,string,int[]>("d", "f", new int[]{1,2,2}),
        new Tuple<string,string,int[]>("y", "z", new int[]{})
    };

    var destination = source.SelectMany(
        tuple => tuple.Item3.Length == 0 ? new int?[] { null } : tuple.Item3.Cast<int?>(),
            (tuple, collectionElement) => new { tuple.Item1, tuple.Item2, collectionElement }
    ).ToList();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接