C # / LINQ: объединение строк - PullRequest
1 голос
/ 14 июля 2011

Есть ли лучший - более функциональный, лаконичный или элегантный - способ написать это? Может быть, функция уменьшения / сгиба?

var key = String.Join(String.Empty,
    new[] {
        keyRoot,
        controllerName,
        actionName
    }.Concat(
        from param in params
        select param.Key + param.Value
    )
);

Входные данные представляют собой несколько переменных, которые являются строками, а также перечислимые соединенные ключи / значения из Dictionary<string, string>.

Выходные данные должны быть связаны со всеми этими строками.

Ответы [ 6 ]

3 голосов
/ 14 июля 2011

Похоже, вы могли бы использовать функцию агрегата LINQ:

Использование LINQ для объединения строк

1 голос
/ 14 июля 2011

Более читабельным для меня было бы что-то вроде этого:

string key = string.Format("{0}{1}{2}{3}", 
                            keyRoot, 
                            controllerName, 
                            actionName, 
                            string.Join(string.Empty, parameters.Select( p =>  p.Key + p.Value)));

Это может быть не так "функционально", но, конечно, так кратко и ясно, как я могу придумать.

0 голосов
/ 03 сентября 2012

Вот решение в одном выражении, использующее Aggregate (фактически сгиб):

var key = params.Aggregate(new StringBuilder()
    .Append(keyRoot)
    .Append(controllerName)
    .Append(actionName),
    (sb, p) => sb.Append(p.Key).Append(p.Value))
    .ToString();
0 голосов
/ 14 июля 2011

Я думаю, что для объединения последовательности всех строк ваша конструкция уже настолько функциональна, насколько вы можете.

Вместо использования String.Join с пустой строкой, я бы, вероятно, использовал StringBuilder вместе с методом расширения ForEach, таким как

public static class MyExtensions {
  public static void ForEach(this IEnumerable<T> enumerable, Action<T> action) {
    foreach (var entry in enumerable)
      action(entry);
  }
}

Я бы также определил локальную переменную для последовательности вроде

var seq = new[] {
                   keyRoot,
                   controllerName,
                   actionName
          }.Concat(
           from param in params select param.Key + param.Value
          );
var sb = new StringBuilder();
seq.ForEach(s=>sb.Append(s));

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

0 голосов
/ 14 июля 2011

С расширением до StringBuilder:

public static class StringBuilderExtensions {

  public static StringBuilder AppendAll(this StringBuilder builder, IEnumerable<string> strings) {
    foreach (string s in strings) builder.Append(s);
    return builder;
  }

}

становится довольно коротким и эффективным:

string key =
  new StringBuilder()
  .Append(keyRoot)
  .Append(controllerName)
  .Append(actionName)
  .AppendAll(parameters.Select(p => p.Key + p.Value))
  .ToString();

Это создаст строку без создания промежуточных массивов.

Единственное, что можно улучшить, - это избегать прерывистых строк p.Key + p.Value, добавляя ключ и значение непосредственно к StringBuilder, но тогда код становится менее пригодным для повторного использования.

Еще одна вещь, которую можно улучшить, это установить емкость StringBuilder, но тогда вам нужно будет выполнить цикл по словарю и сначала добавить длину строки.

(Примечание: я использовал parameters для названия словаря вместо params, так как это ключевое слово.)

0 голосов
/ 14 июля 2011

Это мало что улучшит ...

var key = string.Concat(
   new[] {
    keyRoot,
    controllerName,
    actionName
   }.Concat(
       params.Select(kvp) => param.Key + param.Value)
   ).ToArray ()
);

Это на 2 строки короче, если это не должен быть один оператор.

var list = new List<String> {
    keyRoot,
    controllerName,
    actionName
   };
list.AddRange (params.Select(kvp) => param.Key + param.Value));
var key = string.Concat(list.ToArray ());
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...