使用LINQ动态投影

时间:2014-07-25 15:37:25

标签: c# linq projection

鉴于

(1)数据库表,存储为列表列表。表中行和列的大小未定义。

List<List<string>> table = new List<List<string>>();

例如:

table.Add(new List<string>() { "a1", "b1", "c1", "d1", "e1" });
table.Add(new List<string>() { "a2", "b2", "c2", "d2", "e2" });
table.Add(new List<string>() { "a3", "b3", "c3", "d3", "e3" });
| a1 | b1 | c1 | d1 | e1 |
| a2 | b2 | c2 | d2 | e2 |
| a3 | b3 | c3 | d3 | e3 |

(2)整数列表。这些整数类似于数据库列的索引(从零开始),例如:

List<int> indexes = new List<int>() { 1, 3, 4 };

问题

我的目标是预测列表table中索引出现的indexes列。鉴于以上示例,结果应为:

| b1 | d1 | e1 |
| b2 | d2 | e2 |
| b3 | d3 | e3 |

当前解决方案

我能想到的最好的方法是迭代所有行,如下所示:

List<List<string>> subtable = new List<List<string>>();
for (int index = 0; index < table.Count; index++)
{
    subtable.Add(table[index].Where((t, i) => indexes.Contains(i)).ToList());
}

请求

如果可能的话,这是一个更优雅的解决方案。

3 个答案:

答案 0 :(得分:3)

这个怎么样:

List<List<string>> subtable =
    table.Select(row => indexes.Select(i => row[i]).ToList()).ToList();

如果您需要检查数组边界,可以执行以下操作:

List<List<string>> subtable =
    table.Select(row => indexes.Where(i => i >= 0 && i < row.Count)
                               .Select(i => row[i]).ToList()).ToList();

或者如果您更喜欢查询语法:

List<List<string>> subtable =
    (from row in table
     select
     (from i in indexes
      where i >= 0 && i < row.Count
      select row[i]
     ).ToList()
    ).ToList();

答案 1 :(得分:3)

选择所有行,然后为每一行过滤掉不在索引列表中的列:

var subtable = table
     .Select(row => row.Where((value, colIndex) => indexes.Contains(colIndex)))
     .ToList();

答案 2 :(得分:0)

如果你只想打印,那么在没有这样的查询的情况下更简单(更有效):

        List<List<string>> table = new List<List<string>>();
        table.Add(new List<string>() { "a1", "b1", "c1", "d1", "e1" });
        table.Add(new List<string>() { "a2", "b2", "c2", "d2", "e2" });
        table.Add(new List<string>() { "a3", "b3", "c3", "d3", "e3" });

        List<int> indexes = new List<int>() { 1, 3, 4 };

        for (int index = 0; index < table.Count; index++)
        {
            foreach (var columnIndex in indexes)
                Console.Write(table[index][columnIndex] +" ");

            Console.WriteLine();
        }

        Console.ReadLine();