LINQ中的动态列

时间:2016-02-01 12:09:07

标签: vb.net linq

我尝试使用此代码重写CSV

Shared Sub ReadCSV()

        Dim lines As String() = System.IO.File.ReadAllLines("C:\test.csv")
        Dim lineQuery = From line In lines 
                        Let x = line.Split(New Char() {","}) 
                        Order By x(2) 
                        Select x(2) & ", " & x(1) & ", " & x(0)

        System.IO.File.WriteAllLines("C:\Out.csv ", lineQuery.ToArray())
    End Sub

由于我想改变列数及其顺序,我如何使这部分动态化?

Select x(2) & ", " & x(1) & ", " & x(0)

我希望能够以不同的顺序选择不同数量的列

2 个答案:

答案 0 :(得分:2)

我建议首先将要选择的列表示为索引的列表/数组,然后使用这些列来构建输出。例如(抱歉,我在这里混合使用C#,因为我不知道VB):

// arbitrary set in different orders 
int[] columnsToSelect = new int[] { 3, 2, 1, 5 };

...


Select string.Join(", ", From i In columnsToSelect Select x(i));

string.Join让你将枚举与分隔符字符串连接在一起。在这种情况下,我们的枚举是columnsToSelect列表,其中包含Select投影,用于选择x数组的第i个索引作为每个元素。

答案 1 :(得分:1)

您可以使用以下查询来选择和排序集合中的相关列:

Dim selectColumns = {2, 1, 0}
Dim orderColumns = {0, 1}
Dim maxIndex = selectColumns.Union(orderColumns).Max()

Dim lines = From line In System.IO.File.ReadLines("C:\test.csv")
            Let fields = line.Split(New Char() {","c})
            Select x = New With {.Line = line, .Fields = fields}
            Where x.Fields.Length > maxIndex
            Select x = New With {
                x.Line,
                .Fields = x.Fields.Where(Function(f, index) selectColumns.Contains(index)).ToArray()
            }
            Order By x.Fields(orderColumns(0)) ' presumes at least one order-column '
' Now order the rest of the columns with  Enumerable.ThenBy: '
For Each index As Int32 In orderColumns.Skip(1)
    Dim columnIndex As Int32 = index 'otherwise compiler complains about possible unexpected results(at least in .NET 4) '
    lines = lines.ThenBy(Function(x) x.Fields(columnIndex))
Next

Dim outLines = lines.Select(Function(x) String.Join(",", x.Fields)).ToList()
System.IO.File.WriteAllLines("C:\Out.csv ", outLines)