1

我有以下问题:当我使用

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

我得到:“一,二”

而是预期:"\"one\", \"two\""

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

4

6 回答 6

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(',');
于 2013-11-07T08:09:19.327 回答
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这是这样做的自然方式。

于 2013-11-07T08:16:09.923 回答
1

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

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

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}\"");
于 2013-11-07T08:29:22.660 回答
0

您必须将引号括起来currentc

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

此代码返回预期结果。

于 2013-11-07T08:06:29.147 回答
0

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

var newItems = new[] {"one", "two"};
var a = "The following items will be created: " + 
         newItems.Aggregate("", (current, c) =>
              (current == "" ? "" : current + ", ") + "\"" + c + "\"");
于 2013-11-07T08:08:24.890 回答
0

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

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

结果:

"one", "two"
于 2013-11-07T08:10:08.750 回答