Запятая "Изинг" список предметов - PullRequest
13 голосов
/ 15 декабря 2008

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

Ответы [ 10 ]

32 голосов
/ 15 декабря 2008
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
10 голосов
/ 28 апреля 2009

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

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

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

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

5 голосов
/ 15 декабря 2008

Исходя из ответа 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 декабря 2008

Как это:

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 голосов
/ 23 июля 2009

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

1 голос
/ 15 декабря 2008

Верите ли вы в класс .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 декабря 2008

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

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

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

1 голос
/ 15 декабря 2008

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

псевдокод:

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

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

0 голосов
/ 16 декабря 2008
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 голосов
/ 16 декабря 2008

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

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

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


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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...