2011-07-14 118 views
1

有没有更好的—更实用,简洁或优雅的—这种写法?减少/折叠功能,也许?C#/ LINQ:连接字符串

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

输入是几个变量是字符串,以及级联键/值从Dictionary<string, string>可枚举。

输出应该是所有这些字符串连接。

回答

3

这听起来像你可以使用LINQ聚合函数:

Using LINQ to concatenate strings

+0

只要是明确的:聚合是,事实上,各种所提到的减少/折叠功能这个问题。 –

+0

这种方法唯一的问题是变量'keyRoot','controllerName'和'actionName'与字典不在同一个枚举中,所以你仍然必须使用concat。 – FoobarisMaximus

1

更具可读性我会是这样的:

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

这可能不是“功能性”,但当然我可以提出简洁明了。

0

这并不能改善其多...

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

有延伸到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的容量,但是您需要循环查看字典并首先在upp中添加字符串的长度。

(注:我用parameters的字典,而不是params的名字,因为这是一个关键字)

0

我觉得对于连接所有字符串的顺序,你的结构已经为功能,你可以得到。

而不是使用String.Join为空字符串的,我可能会连同ForEach extenstion方法使用StringBuilder

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

以下是在一个表达式中使用Aggregate的溶液(有效地折叠):

var key = params.Aggregate(new StringBuilder() 
    .Append(keyRoot) 
    .Append(controllerName) 
    .Append(actionName), 
    (sb, p) => sb.Append(p.Key).Append(p.Value)) 
    .ToString();