代码之家  ›  专栏  ›  技术社区  ›  TheHolyTerrah

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

  •  3
  • TheHolyTerrah  · 技术社区  · 16 年前

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

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

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

    B

    C

    D

    E

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

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

    8 回复  |  直到 16 年前
        1
  •  11
  •   Quintin Robinson    16 年前

    你试过简单的连接吗?。。

    .ToArray() 将集合转换为数组。

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

    VB

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

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

    field.Values.Aggregate(string.Empty, (s1, s2) => s1 += Environment.NewLine + s2);
    
        2
  •  2
  •   bendewey    16 年前

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

    用法:

    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, ",");
        }
    }
    
        3
  •  1
  •   John Fisher    16 年前

    您可以使用Aggregate方法实现这一点,但它的效率远不如附加到文件或StringBuilder的foreach循环。

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

        4
  •  1
  •   Guffa    16 年前

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

    Dim fileContent As String = _
       field.Values.Aggregate( _
          New StringBuilder(), _
          Function(b, i) b.AppendLine(i) _
       ).ToString()
    
        5
  •  1
  •   Matt Hamilton    16 年前

    请注意,.NET4.0包含一个新的 String.Concat<T>() IEnumerable<T>

        6
  •  0
  •   Indeed is Trash    16 年前

    如果 Values 是一个列表,你可以这样做。。。

    field.Values.ForEach(o=>fileContent.Append(o + Environment.NewLine));
    
        7
  •  0
  •   Cam Soper    16 年前

    IEnumerable.Aggregate .

    您的代码将如下所示:

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

        8
  •  0
  •   Dan Appleyard    16 年前

    创建一个扩展方法-

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