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

时间:2015-04-10 12:21:16

标签: c# linq

我正在尝试转换以下集合:

来源

"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()方法,但我似乎可以确定答案。

问题类似于:How do I select a collection within a collection using LINQ?对集合进行非规范化处理,但没有说明如何包含相关列(在我的示例中为第1列和第2列)。

不同之处在于我需要包含前两列,并且还返回一个集合中没有条目的行。

3 个答案:

答案 0 :(得分: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);

答案 1 :(得分:2)

假设SrcDst的元素有一些合适的类型SourceDestination。然后,类似于文档中的example,可以使用以下语句解决任务。

Dest = Source.SelectMany(
    iSrc => iSrc.Third,
    (iSrc,No) => new Dest(){ First = iSrc.First,
                             Second = iSrc.Second,
                             Third = No
                           }
);

答案 2 :(得分: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();