Linq - 使用引号聚合字符串

时间:2013-11-07 08:00:20

标签: c# string linq aggregate-functions

我有以下问题: 当我使用

 var newItems = {"one", "two"}
 var a = newItems.Aggregate((current, c) => current + ", \"" + c + "\"");

我得到:“一,二”

取而代之的是:“\”一个\“,\”两个“”“

谁可以向我解释为什么会这样?

6 个答案:

答案 0 :(得分:3)

你应该这样做

string output=String.Join(",",newItems.Select(x=>"\""+x+"\""));

替代解决方案

StringBuilder sb=new StringBuilder();
newItems.ToList()
        .ForEach(x=>sb.Append(","+String.Format("\"{0}\"",x)));
string output=sb.ToString().Trim(',');

答案 1 :(得分:1)

将聚合与字符串一起使用并不是一个好主意,因为它会在每次迭代时在内存中创建新的字符串。我建议您使用String.Join(内部使用StringBuilder)或直接使用StringBuilder作为累加器:

var a = newItems.Aggregate(
          new StringBuilder(), // avoid intermediate strings creation
          (sb, s) => sb.AppendFormat("{0}\"{1}\"", sb.Length > 0 ? "," : "", s),
          sb => sb.ToString());

因此,你不仅想要连接字符串,还要用一些符号加入它们,那么String.Join就是这样做的自然方式。

答案 2 :(得分:1)

您应该尽可能避免使用字符串连接。字符串是不可变的,因此连接字符串会创建新的临时字符串,以后必须进行垃圾回收。如果您定期执行许多字符串操作,这可能是一个严重的问题。

您可以使用String.JoinString.Forma t从值列表中创建分隔字符串,如下所示:

var newItems = new [] {"one", "two"};
var a = String.Join(", ",newItems.Select(c => String.Format("\"{0}\"",c)));

这会创建临时字符串,尽管它们比以前少得多。

您也可以使用StringBuilder和Aggregate创建单个字符串并避免使用任何临时字符串,尽管代码看起来有点难看:

var builder = new StringBuilder();
var b1 = (newItems.Aggregate(builder,
            (bld, c) => bld.AppendFormat("\"{0}\",", c),
            bld => bld.Remove(bld.Length - 1, 1))
         ).ToString();

甚至

 var b2 = newItems.Aggregate(builder2, 
         (bld, c) => bld.AppendFormat("\"{0}\",", c), 
         bld => bld.Remove(bld.Length - 1, 1).ToString());

如果您需要在许多地方使用此类代码,最好在扩展方法中隐藏整个构造:

public static string JoinFormat<T>(this IEnumerable<T> items,string format)
{
    var builder = new StringBuilder();
    var result = (items.Aggregate(builder,
            (bld, c) => bld.AppendFormat(format, c),
            bld => bld.Remove(bld.Length - 1, 1))
         ).ToString();
    return result;
}

并写:

var a=newItems.JoinFormat("\"{0}\"");

答案 3 :(得分:0)

您必须将currentc括在引号周围:

var a = newItems.Aggregate((current, c) => "\"" + current + "\", \"" + c + "\"");

此代码返回预期结果。

答案 4 :(得分:0)

默认情况下,Aggregate将获取其第一个值并将其用作种子,因此需要one并将, "two"附加到其中。你需要做的是指定一个空白的种子并做一些特殊的事情(即不用逗号)你得到一个空白的种子:

var newItems = new[] {"one", "two"};
var a = "The following items will be created: " + 
         newItems.Aggregate("", (current, c) =>
              (current == "" ? "" : current + ", ") + "\"" + c + "\"");

答案 5 :(得分:0)

您忘记将前一个和当前元素嵌入引号中:

var newItems = new[]{"one", "two"};
var strout = '"' + newItems.Aggregate((a, b) =>  a +  "\", \"" + b)+ '"';

结果:

"one", "two"