Запятая «Изинг» список предметов

Учитывая список строк, каков наилучший метод для объединения этих строк в список через запятую без запятой в конце. (VB.NET или C #) (с использованием StringBuilder или String Concat.)

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)
15.12.2008 14:38:12
10 ОТВЕТОВ
Dim Result As String
Dim Items As New List(Of String)
Items.Add("Hello")
Items.Add("World")

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

Если вы действительно беспокоитесь о пустых строках, используйте эту функцию соединения:

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
32
16.12.2008 02:48:35

Есть несколько способов сделать это, но они в основном вариации на тему.

псевдокод:

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
15.12.2008 14:43:54

или вы можете сделать:

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

Установив разделитель на пустую строку в первой итерации, вы пропускаете первую запятую. На одно меньше, если заявление. Это может или не может быть более читабельным в зависимости от того, что вы привыкли

1
15.12.2008 14:49:02

Нравится:

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();
    }
}
5
15.12.2008 15:06:54

Исходя из ответа String.Join, чтобы игнорировать пустые / пустые строки (и если вы используете .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)
5
15.12.2008 16:10:04
Я люблю это. Я даже не думал об использовании linq для этого ... Что не может сделать linq?
Nick 17.09.2012 02:55:12

Верите ли вы в класс .NET Framework, который предоставляет эту функциональность?

public static string ListToCsv<T>(List<T> list)
        {
            CommaDelimitedStringCollection commaStr = new CommaDelimitedStringCollection();

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


            return commaStr.ToString();
        }
1
15.12.2008 15:48:26

Спасибо за все ответы.

Похоже, что «правильный» ответ зависит от контекста, в котором создается разделенный запятыми список. У меня нет аккуратного списка элементов для использования (пришлось что-то использовать для примера ...), но у меня есть массив, элементы которого могут или не могут быть добавлены в разделенный запятыми список в зависимости от различных условий.

Поэтому я выбрал что-то с эффектом


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
16.12.2008 02:07:52
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() function

0
10.06.2012 03:36:34

Решение должно использовать StringBuilderили Concatметод?

Если нет, вы можете использовать статический String.Joinметод. Например (в C #):

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

Смотрите мой очень похожий вопрос для более подробной информации по этому вопросу.

10
23.05.2017 11:44:46

Если вам не нужно использовать StringBuilderили Concatметод, вы также можете использовать:

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

2
23.07.2009 19:33:23