逗号"化"清单列表

13

给定一个字符串列表,使用StringBuilder或String Concat,将这些字符串连接成一个没有末尾逗号的逗号分隔列表,最佳方法是什么?(VB.NET或C#)

Dim strResult As String = ""
Dim lstItems As New List(Of String)
lstItems.Add("Hello")
lstItems.Add("World")
For Each strItem As String In lstItems
    If strResult.Length > 0 Then
        strResult = strResult & ", "
    End If
    strResult = strResult & strItem
Next
MessageBox.Show(strResult)
10个回答

33
Dim Result As String
Dim Items As New List(Of String)
Items.Add("Hello")
Items.Add("World")

Result = String.Join(",", Items)
MessageBox.Show(Result)

如果你真的担心空字符串,可以使用这个 join 函数:

Function Join(ByVal delimiter As String, ByVal items As IEnumerable(Of String), Optional ByVal IgnoreEmptyEntries As Boolean = True) As String
    Dim delim As String = ""
    Dim result As New Text.StringBuilder("")

    For Each item As String In items
        If Not IgnoreEmptyEntries OrElse Not String.IsNullOrEmpty(item) Then
            result.Append(delim).Append(item)
            delim = delimiter
        End If
    Next
    Return result.ToString()
End Function

上面的做法非常老旧。今天,我会像这样清除空字符串:

Dim Result As String = String.Join("," Items.Where(Function(i) Not String.IsNullOrWhitespace(i)))

10

这个解决方案是否必须使用StringBuilder或Concat方法?

如果不是,您可以使用静态的String.Join方法。例如(在C#中):

string result = String.Join(",", items.ToArray());

请参阅我的非常相似的问题,以获取更多关于此内容的详细信息。


5

接着上面的String.Join答案,如果想忽略空字符串或null(如果你使用的是.NET 3.5),可以使用一些Linq技巧。例如:

Dim Result As String
Dim Items As New List(Of String)
Items.Add("Hello")
Items.Add("World")
Result = String.Join(",", Items.ToArray().Where(Function(i) Not String.IsNullOrEmpty(i))
MessageBox.Show(Result)

我喜欢它。我甚至没想过用linq来做这个... linq究竟能做什么? - Nick

5

就像这样:

lstItems.ToConcatenatedString(s => s, ", ")

如果你想像你的例子一样忽略空字符串:
lstItems
    .Where(s => s.Length > 0)
    .ToConcatenatedString(s => s, ", ")

我工具箱中最受欢迎的自定义聚合函数。我每天都在使用它:

public static class EnumerableExtensions
{

    /// <summary>
    /// Creates a string from the sequence by concatenating the result
    /// of the specified string selector function for each element.
    /// </summary>
    public static string ToConcatenatedString<T>(
        this IEnumerable<T> source,
        Func<T, string> stringSelector)
    {
        return EnumerableExtensions.ToConcatenatedString(source, stringSelector, String.Empty);
    }

    /// <summary>
    /// Creates a string from the sequence by concatenating the result
    /// of the specified string selector function for each element.
    /// </summary>
    /// <param name="separator">The string which separates each concatenated item.</param>
    public static string ToConcatenatedString<T>(
        this IEnumerable<T> source,
        Func<T, string> stringSelector,
        string separator)
    {
        var b = new StringBuilder();
        bool needsSeparator = false; // don't use for first item

        foreach (var item in source)
        {
            if (needsSeparator)
                b.Append(separator);

            b.Append(stringSelector(item));
            needsSeparator = true;
        }

        return b.ToString();
    }
}

2

如果您不必使用StringBuilderConcat方法,您也可以使用:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Net;
using System.Configuration;

namespace ConsoleApplication
{
    class Program
    {
        static void Main(string[] args)
        {
            CommaDelimitedStringCollection commaStr = new CommaDelimitedStringCollection();
            string[] itemList = { "Test1", "Test2", "Test3" };
            commaStr.AddRange(itemList);
            Console.WriteLine(commaStr.ToString()); //Outputs Test1,Test2,Test3
            Console.ReadLine();
        }
    }
}

这需要引用System.Configuration。

1

有几种方法可以做到这一点,但它们基本上是主题的变化。

伪代码:

For Each Item In Collection:
  Add Item To String
  If Not Last Item, Add Comma

我喜欢的另一种方式是这样的:
For Each Item In Collection:
  If Not First Item, Add Comma
  Add Item To String

编辑:我喜欢第二种方法的原因是每个项目都是独立的。使用第一种方法,如果您稍后修改了逻辑,以便可能不添加后续项目,则除非您还使先前项目中的测试更加智能,否则您可能会在字符串末尾留下一个杂项逗号,这很愚蠢。


1

或者你可以这样做:

Separator = ""
For Each Item In Collection
  Add Separator + Item To String
  Separator = ", "

在第一次迭代中将分隔符设置为空字符串,可以跳过第一个逗号。少了一个if语句。这可能更易读,具体取决于您习惯什么样的写法。


1
你相信在.NET框架中有一个类可以提供这种功能吗?
public static string ListToCsv<T>(List<T> list)
        {
            CommaDelimitedStringCollection commaStr = new CommaDelimitedStringCollection();

            list.ForEach(delegate(T item)
            {
                commaStr.Add(item.ToString());
            });


            return commaStr.ToString();
        }

0

感谢所有的回复。

看起来,“正确”的答案取决于构建逗号分隔列表的上下文。我没有一个整洁的项目清单可供使用(必须使用一些示例......),但是我有一个数组,其项目可能会根据各种条件添加到逗号分隔的列表中。

因此,我选择了类似于


strResult = ""
strSeparator = ""
for i as integer = 0 to arrItems.Length - 1
  if arrItems(i) <> "test" and arrItems(i) <> "point" then
    strResult = strResult & strSeparator & arrItem(i)
    strSeparator = ", "
  end if
next

通常情况下,有许多方法可以做到这一点。我不知道哪种方法值得更多的赞扬或推广。有些在某些情境下更有用,而其他的则满足不同情境的要求。
再次感谢大家的意见。
顺便说一句,原始帖子中的“脑海中”代码示例没有过滤零长度项,而是等待结果字符串变为大于零长度后再添加逗号。可能不太高效,但我还没有测试过。再次强调,那只是我的想法。

0
Dim strResult As String = ""
Dim separator = ","
Dim lstItems As New List(Of String)
lstItems.Add("Hello")
lstItems.Add("World")
For Each strItem As String In lstItems
     strResult = String.Concat(strResult, separator)
Next
strResult = strResult.TrimEnd(separator.ToCharArray())
MessageBox.Show(strResult)

这个想法是使用 String.TrimEnd() 函数


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接