Vb.net 如何使用Linq从集合构建字符串?

Vb.net 如何使用Linq从集合构建字符串?,vb.net,linq,string,Vb.net,Linq,String,我正在从字符串集合构建平面文件内容 示例集合:A、B、C、D、E等 如果可能的话,我希望能够使用Linq一次性将这些值输出到带有换行符的字符串中 样本输出: A B C D E 等等 以下是当前执行此任务的VB.NET代码: For Each fieldValue As String In field.Values fileContent.Append(fieldValue + Environment.NewLine) Next 我尝试了很多方法让Linq来做这项工作,但是没有找到正确的

我正在从字符串集合构建平面文件内容

示例集合:A、B、C、D、E等

如果可能的话,我希望能够使用Linq一次性将这些值输出到带有换行符的字符串中

样本输出:

A

B

C

D

E

等等

以下是当前执行此任务的VB.NET代码:

For Each fieldValue As String In field.Values
   fileContent.Append(fieldValue + Environment.NewLine)
Next

我尝试了很多方法让Linq来做这项工作,但是没有找到正确的组合。想法?

您尝试过简单的加入吗

如果field.Values已经是字符串数组,那么这应该可以正常工作。。否则,您可以使用LINQ
.ToArray()
将集合转换为数组

string joined = string.Join(Environment.NewLine, field.Values);
VB

我想我会补充一句,如果你真的,真的只是想用LINQ做这件事,Aggregate会有用的,尽管我不会真的建议你这样做

field.Values.Aggregate(string.Empty, (s1, s2) => s1 += Environment.NewLine + s2);

如果
Values
是一个列表,则可以执行此操作

field.Values.ForEach(o=>fileContent.Append(o + Environment.NewLine));

我创建了这些扩展方法,可以用来连接集合中任意数量的项。举例来说,这可能有点过分,但如果您需要连接对象而不是字符串的项,它可以很好地工作

用法: 扩展:
公共静态类EnumerableExtensions
{
公共静态字符串连接(此IEnumerable源,字符串分隔符)
{
返回Concatenate(source,i=>i.ToString(),分隔符);
}
公共静态字符串连接(此IEnumerable源、Func选择器、字符串分隔符)
{
var builder=新的StringBuilder();
foreach(源中的var项)
{
如果(builder.Length>0)
builder.Append(分隔符);
附加(选择器(项));
}
返回builder.ToString();
}
公共静态字符串ToCsv(此IEnumerable源)
{
返回Concatenate(source,i=>i.ToString(),“,”);
}
公共静态字符串ToCsv(此IEnumerable源,Func选择器)
{
返回连接(源,选择器,“,”);
}
}

您可以使用聚合方法来实现,但它的效率远不如附加到文件或StringBuilder的foreach循环

我相信您的基本问题是Linq的正确用法是返回结果。设计者不希望您使用Linq语句来修改它正在迭代的对象。这很可能解释了你在这项任务中遇到的普遍困难

不要忘记foreach是使用Linq结果的正确方法

您可能需要使用

您的代码将如下所示:

Dim fileContentString As String = _
        field.Values.Aggregate(Function(ByVal JoinedValues, ByVal DiscreteValue) 
            JoinedValues & Environment.NewLine & DiscreteValue)

免责声明-仅仅因为你可以使用Linq,并不意味着它是这个工作的正确工具。正如其他人所指出的,ForEach循环将更有效。

您可以在聚合扩展方法中使用StringBuilder:

Dim fileContent As String = _
   field.Values.Aggregate( _
      New StringBuilder(), _
      Function(b, i) b.AppendLine(i) _
   ).ToString()

创建扩展方法-

<Extension()> _
Public Function Flatten(ByVal stringList As IList(Of String), ByVal delimiter As String) As String
        Dim strB As New StringBuilder

        For Each Str As String In stringList
            If strB.ToString.Length > 0 Then
                strB.Append(delimiter)
            End If
            strB.Append(Str)
        Next
        Return strB.ToString
    End Function

请注意,.NET4.0包含了一个新的静态方法,它接受一个
IEnumerable
,并对列表中的每个对象调用ToString。应该会派上用场的

杰森,VB9中没有foreach,是个小错误,长官。投票支持你的帮助。至少我知道在v4.0中会发生什么!非常接近连接。但它是一个集合,所以我必须先转换它,然后在末尾添加另一个换行符。fileContent.Append(String.Join(Environment.NewLine,field.Values.ToArray())+Environment.NewLine)不能仅仅为了使用LINQ而使用LINQ。我认为您的String.Join解决方案比任何LINQ解决方案都要好;-)@Boydski我很高兴你得到了你想要的解决方案@Meta Knight我同意我开始尽可能多地观看v4.0的内容。谢谢你的建议!
Dim fileContentString As String = _
        field.Values.Aggregate(Function(ByVal JoinedValues, ByVal DiscreteValue) 
            JoinedValues & Environment.NewLine & DiscreteValue)
Dim fileContent As String = _
   field.Values.Aggregate( _
      New StringBuilder(), _
      Function(b, i) b.AppendLine(i) _
   ).ToString()
<Extension()> _
Public Function Flatten(ByVal stringList As IList(Of String), ByVal delimiter As String) As String
        Dim strB As New StringBuilder

        For Each Str As String In stringList
            If strB.ToString.Length > 0 Then
                strB.Append(delimiter)
            End If
            strB.Append(Str)
        Next
        Return strB.ToString
    End Function
Dim letters as New List(Of String)
'do your loading of the list

Dim formattedString As String = letters.Flatten(Environment.NewLine)