Подтвердить что ты не робот

Заблокировать список элементов

Учитывая список строк, каков наилучший способ объединения этих строк в список, разделенный запятыми, без запятой в конце. (VB.NET или С#) (используя либо 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)
4b9b3361

Ответ 1

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

Ответ 2

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

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

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

Подробнее об этом см. мой очень похожий вопрос.

Ответ 3

Вот так:

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();
    }
}

Ответ 4

Идти из ответа 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

Если вам не нужно использовать метод 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

Ответ 6

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

псевдокод:

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

Изменить: Причина, по которой мне нравится второй способ сделать это, состоит в том, что каждый элемент стоит сам по себе. Используя первый подход, если позже вы изменили свою логику, чтобы последующий элемент не мог быть добавлен, вы могли бы получить блуждающую запятую в конце строки, если бы вы не сделали ваш тест в предыдущем элементе более интеллектуальным, что немой.

Ответ 7

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

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

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

Ответ 8

Не могли бы вы поверить в класс в платформе .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();
        }

Ответ 9

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

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

Итак, я выбрал что-то вроде


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

Как обычно, существует множество способов сделать это. Я не знаю, что любой метод заслуживает большего похвалы или продвижения по службе, чем другой. Некоторые из них более полезны в определенных контекстах, тогда как другие удовлетворяют требованиям различных контекстов.

Опять же, спасибо всем за ваш вклад.

Кстати, исходный пост с образцом кода "с верхней части моей головы" не фильтрует элементы с нулевой длиной, а ожидает, что строка результата станет больше нулевой длины перед добавлением запятой. Наверное, не очень эффективный, но я его не тестировал. Опять же, это было не в моей голове.

Ответ 10

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