如何使用Linq从集合中构建字符串?

时间:2009-10-08 20:22:16

标签: vb.net linq string

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

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

我希望能够将这些值输出到带有换行符的字符串中,如果可能的话,将其与Linq一起输出。

示例输出:

A

C

d

电子

这是当前完成工作的VB.NET代码:

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

我尝试了很多方法让Linq完成这项工作,但未能找到合适的组合。想法?

8 个答案:

答案 0 :(得分:11)

您尝试过简单的加入吗?..

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

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

VB

Dim joined As String = String.Join(Environment.NewLine, field.Values)

我想补充一点,如果你真的,真的只是想用LINQ做这个,聚合就行了,虽然我不会真的推荐这个来满足你的需求。

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

答案 1 :(得分:2)

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

用法:

fileContent = field.Values.Contatenate(Environment.NewLine);

扩展:

public static class EnumerableExtensions
{
    public static string Concatenate<T>(this IEnumerable<T> source, string seperator)
    {
        return Concatenate(source, i => i.ToString(), seperator);
    }

    public static string Concatenate<T>(this IEnumerable<T> source, Func<T, string> selector, string seperator)
    {
        var builder = new StringBuilder();
        foreach (var item in source)
        {
            if (builder.Length > 0)
                builder.Append(seperator);

            builder.Append(selector(item));
        }
        return builder.ToString();
    }

    public static string ToCsv<T>(this IEnumerable<T> source)
    {
        return Concatenate(source, i => i.ToString(), ",");
    }

    public static string ToCsv<T>(this IEnumerable<T> source, Func<T, string> selector)
    {
        return Concatenate(source, selector, ",");
    }
}

答案 2 :(得分:1)

您可以使用Aggregate方法实现目标,但它不会像附加到文件或StringBuilder的foreach循环那样高效。

我相信你的基本问题是Linq的正确用法是返回结果。设计人员并不打算使用Linq语句来修改它迭代的对象。这可能解释了你在完成这项任务时遇到的一般困难。

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

答案 3 :(得分:1)

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

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

答案 4 :(得分:1)

请注意,.NET 4.0包含一个新的String.Concat<T>()静态方法,它接受IEnumerable<T>并在列表中的每个对象上调用ToString。应该派上用场了!

答案 5 :(得分:0)

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

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

答案 6 :(得分:0)

您可能想要使用IEnumerable.Aggregate

您的代码将如下所示:

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

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

答案 7 :(得分:0)

创建扩展方法 -

<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)