Присоедините строку, используя разделители - PullRequest
22 голосов
/ 24 февраля 2009

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

РЕДАКТИРОВАТЬ: я не использовал StringBuilder, чтобы сделать код немного проще.

Используйте цикл For *

for(int i=0; i < list.Length; i++)
{
    result += list[i];
    if(i != list.Length - 1)
        result += delimiter;
}

Использовать For Loop для установки первого элемента ранее

result = list[0];
for(int i = 1; i < list.Length; i++)
    result += delimiter + list[i];

Они не будут работать для IEnumerable, где вы заранее не знаете длину списка, поэтому

Использование цикла foreach

bool first = true;
foreach(string item in list)
{
    if(!first)
        result += delimiter;
    result += item;
    first = false;
}

Изменение цикла по каждому элементу

Из решения Джона

StringBuilder builder = new StringBuilder();
string delimiter = "";
foreach (string item in list)
{
    builder.Append(delimiter);
    builder.Append(item);
    delimiter = ",";       
}
return builder.ToString();

Использование итератора

Снова от Джона

using (IEnumerator<string> iterator = list.GetEnumerator())
{
    if (!iterator.MoveNext())
        return "";
    StringBuilder builder = new StringBuilder(iterator.Current);
    while (iterator.MoveNext())
    {
        builder.Append(delimiter);
        builder.Append(iterator.Current);
    }
    return builder.ToString();
}

Какие еще есть алгоритмы?

Ответы [ 24 ]

1 голос
/ 24 февраля 2009

Я думаю, что лучший способ сделать что-то подобное (я буду использовать псевдокод, поэтому мы сделаем его по-настоящему независимым от языка):

function concat(<array> list, <boolean> strict):
  for i in list:
    if the length of i is zero and strict is false:
      continue;
    if i is not the first element:
      result = result + separator;
    result = result + i;
  return result;

второй аргумент concat(), strict - это флаг, который определяет, нужно ли рассматривать возможные пустые строки в конкатенации или нет.

Я привык не рассматривать добавление окончательного разделителя; с другой стороны, если для параметра false установлено значение false, в результирующей строке не должно быть символов, таких как «A, B ,,, F», при условии, что разделитель является запятой, но вместо этого будет представлен как «A, B, F».

1 голос
/ 10 апреля 2009

видел ответ Python как 3 раза, но без Ruby?!?!?

первая часть кода объявляет новый массив. Затем вы можете просто вызвать метод .join () и передать разделитель, и он вернет строку с разделителем в середине. Я полагаю, что метод join вызывает метод .to_s для каждого элемента перед его объединением.

["ID", "Description", "Active"].join(",")
>> "ID, Description, Active"

это может быть очень полезно при сочетании метапрограммирования с взаимодействием с базой данных.

кто-нибудь знает, есть ли в c # что-то похожее на этот синтаксис сахар?

1 голос
/ 24 февраля 2009

Поскольку вы пометили этот язык как независимый,

Вот как бы вы сделали это в python

# delimiter can be multichar like "| trlalala |"
delimiter = ";"
# sequence can be any list, or iterator/generator that returns list of strings
result = delimiter.join(sequence)
#result will NOT have ending delimiter 

Редактировать: Я вижу, что меня избили несколько человек. Извините за дублирование

1 голос
/ 22 декабря 2014

В Java 8 мы можем использовать:

List<String> list = Arrays.asList(new String[] { "a", "b", "c" });
System.out.println(String.join(",", list)); //Output: a,b,c

Чтобы иметь префикс и суффикс, мы можем сделать

StringJoiner joiner = new StringJoiner(",", "{", "}");
list.forEach(x -> joiner.add(x));
System.out.println(joiner.toString()); //Output: {a,b,c}

До Java 8 вы можете сделать как ответ Джона

StringBuilder sb = new StringBuilder(prefix);
boolean and = false;
for (E e : iterable) {        
    if (and) {
        sb.append(delimiter);
    }
    sb.append(e);
    and = true;
}
sb.append(suffix);
1 голос
/ 24 февраля 2009

Это рабочее решение в C #, в Java вы можете использовать подобное для каждого итератора.

        string result = string.Empty; 

        // use stringbuilder at some stage.
        foreach (string item in list)
            result += "," + item ;

        result = result.Substring(1);
        // output:  "item,item,item"

Если вы используете .NET, вы можете использовать метод расширения, чтобы вы могли сделать list.ToString ( "") За подробностями обращайтесь к ToString с разделителями-разделителями для массива, списка, словаря, универсального IEnumerable

// contains extension methods, it must be a static class.
public static class ExtensionMethod
{
    // apply this extension to any generic IEnumerable object.
    public static string ToString<T>(this IEnumerable<T> source,
      string separator)
    {
        if (source == null)
           throw new ArgumentException("source can not be null.");

        if (string.IsNullOrEmpty(separator))
           throw new ArgumentException("separator can not be null or empty.");

        // A LINQ query to call ToString on each elements
        // and constructs a string array.
        string[] array =
         (from s in source
          select s.ToString()
          ).ToArray();

        // utilise builtin string.Join to concate elements with
        // customizable separator.
        return string.Join(separator, array);
    }
}

РЕДАКТИРОВАТЬ: Из соображений производительности замените код конкатенации на решение для построения строк, упомянутое в этом потоке.

0 голосов
/ 24 февраля 2009

Вот как Python решает проблему:

','.join(list_of_strings)

Я никогда не мог понять необходимость «алгоритмов» в тривиальных случаях, хотя

0 голосов
/ 02 августа 2010

Groovy также имеет метод String Object.join (String).

0 голосов
/ 11 июня 2009

В Clojure вы можете просто использовать clojure.contrib.str-utils / str-join:

(str-join ", " list)

Но для фактического алгоритма:

(reduce (fn [res cur] (str res ", " cur)) list)
0 голосов
/ 05 июня 2009

Для Java был дан очень полный ответ на этот вопрос или на этот вопрос .

То есть использовать StringUtils.join в Apache Commons

String result = StringUtils.join(list, ", ");
0 голосов
/ 24 февраля 2009

Вы можете написать свой собственный метод AppendTostring (string, delimiter), который добавляет разделитель тогда и только тогда, когда строка не пуста. Затем вы просто вызываете этот метод в любом цикле, не беспокоясь о том, когда добавлять, а когда не добавлять.

Редактировать: еще лучше, конечно, использовать какой-то тип StringBuffer в методе, если он доступен.

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