最有效的编写老派代码的方法是什么:
StringBuilder sb = new StringBuilder();
if (strings.Count > 0)
{
foreach (string s in strings)
{
sb.Append(s + ", ");
}
sb.Remove(sb.Length - 2, 2);
}
return sb.ToString();
如何在LINQ中使用?
最有效的编写老派代码的方法是什么:
StringBuilder sb = new StringBuilder();
if (strings.Count > 0)
{
foreach (string s in strings)
{
sb.Append(s + ", ");
}
sb.Remove(sb.Length - 2, 2);
}
return sb.ToString();
如何在LINQ中使用?
Aggregate
),以满足问题的要求,但不适用于日常使用。因为它没有使用StringBuilder
,所以对于非常长的序列来说性能很差。在正常的代码中,请使用如其他answer所示的String.Join
。string[] words = { "one", "two", "three" };
var res = words.Aggregate(
"", // start with empty string to handle empty list case.
(current, next) => current + ", " + next);
Console.WriteLine(res);
这将输出:
,one,two,three
聚合函数是一种接受值集合并返回标量值的函数。在 T-SQL 中的示例包括 min、max 和 sum。VB 和 C# 都支持聚合函数。VB 和 C# 都支持将聚合函数作为扩展方法。使用点符号表示法,只需在 IEnumerable 对象上调用一个方法。
请记住,聚合查询会立即执行。
更多信息 - MSDN: 聚合查询
Aggregate
,请使用CodeMonkeyKing在评论中提出的使用StringBuilder
的变体,这将是与常规String.Join
相同的代码,包括大量对象的良好性能。 var res = words.Aggregate(
new StringBuilder(),
(current, next) => current.Append(current.Length == 0? "" : ", ").Append(next))
.ToString();
""
作为种子值,所以 current
中使用的第一个值是空字符串。因此,对于一个或多个元素,你总会在字符串开头得到 ,
。 - Michael Yannireturn string.Join(", ", strings.ToArray());
在 .Net 4 中, string.Join
有一个新的重载方法,接受 IEnumerable<string>
。代码看起来像这样:return string.Join(", ", strings);
为什么要使用Linq?
string[] s = {"foo", "bar", "baz"};
Console.WriteLine(String.Join(", ", s));
据我所记,这可以完美地运行并接受任何 IEnumerable<string>
。这里不需要使用Aggregate
,因为它会慢很多。
String.Join(",", s.ToArray())
。 - Martijn你看过Aggregate扩展方法吗?
var sa = (new[] { "yabba", "dabba", "doo" }).Aggregate((a,b) => a + "," + b);
我的代码中的真实例子:
return selected.Select(query => query.Name).Aggregate((a, b) => a + ", " + b);
查询是一个对象,它有一个名为Name的属性,该属性是一个字符串。我想要选定列表中所有查询的名称,并以逗号分隔。
下面是我在查看其他答案和类似问题(即Aggregate和Concatenate在0个元素时会失败)后决定采用的结合了Join/Linq的方法:
string Result = String.Join(",", split.Select(s => s.Name));
或者(如果s
不是字符串)
string Result = String.Join(",", split.Select(s => s.ToString()));
StringBuilder
)来实现当然,Join会处理有时会出现的讨人厌的末尾逗号(如for
、foreach
),这也是我最初寻找Linq解决方案的原因。
.Select()
提供了一个很容易的地方来修改每个元素。例如,像这样将每个项目包装在某个字符中string Result = String.Join(",", split.Select(s => "'" + s + "'"));
。 - Sam StorieAggregate
中使用StringBuilder
: List<string> strings = new List<string>() { "one", "two", "three" };
StringBuilder sb = strings
.Select(s => s)
.Aggregate(new StringBuilder(), (ag, n) => ag.Append(n).Append(", "));
if (sb.Length > 0) { sb.Remove(sb.Length - 2, 2); }
Console.WriteLine(sb.ToString());
(Select
只是为了展示你可以在LINQ中做更多的事情。)
new[] {"one", "two", "three"}.Aggregate(new StringBuilder(), (sb, s) =>{if (sb.Length > 0) sb.Append(", ");sb.Append(s);return sb;}).ToString();
- dss539if (length > 0)
并将其删除,您可以节省宝贵的时钟周期。 - Binoj Antonynew[] {"", "one", "two", "three"}.Aggregate(new StringBuilder(), (sb, s) => (String.IsNullOrEmpty(sb.ToString())) ? sb.Append(s) : sb.Append(", ").Append(s)).ToString();
。 - ProfNimrodsb.ToString()
)。 (它还检查永远不可能为空的东西是否为空。)您完全失去了使用StringBuffer的优势,这与仅串联字符串一样糟糕。 - andrewf以下是针对 3000 个元素,StringBuilder 和 Select & Aggregate 的快速性能数据:
单元测试 - 持续时间(秒)
LINQ_StringBuilder - 0.0036644
LINQ_Select.Aggregate - 1.8012535
[TestMethod()]
public void LINQ_StringBuilder()
{
IList<int> ints = new List<int>();
for (int i = 0; i < 3000;i++ )
{
ints.Add(i);
}
StringBuilder idString = new StringBuilder();
foreach (int id in ints)
{
idString.Append(id + ", ");
}
}
[TestMethod()]
public void LINQ_SELECT()
{
IList<int> ints = new List<int>();
for (int i = 0; i < 3000; i++)
{
ints.Add(i);
}
string ids = ints.Select(query => query.ToString())
.Aggregate((a, b) => a + ", " + b);
}
我总是使用扩展方法:
public static string JoinAsString<T>(this IEnumerable<T> input, string seperator)
{
var ar = input.Select(i => i.ToString());
return string.Join(seperator, ar);
}
string.Join
可以接受任意类型T
的IEnumerable<T>
。 - recursive“超酷LINQ方式” 可能是指使用扩展方法让函数式编程更易接受的方式。我指的是一种语法糖,它允许将函数以视觉线性方式(一个接一个)连接在一起,而不是嵌套在一起。例如:
int totalEven = Enumerable.Sum(Enumerable.Where(myInts, i => i % 2 == 0));
可以这样写:
int totalEven = myInts.Where(i => i % 2 == 0).Sum();
第二个例子更易于阅读,同时您还可以看到如何使用更少的缩进问题或Lispy关闭圆括号出现在表达式末尾时添加更多的函数。
很多其他答案都说String.Join
是最快或最简单的方式。但如果你采纳我的“超酷LINQ方式”的解释,那么答案是使用String.Join
并将其包装在一个LINQ风格的扩展方法中,这样您就可以以视觉上令人愉悦的方式链接您的函数。因此,如果您想编写sa.Concatenate(", ")
,只需创建类似于以下内容的东西:
public static class EnumerableStringExtensions
{
public static string Concatenate(this IEnumerable<string> strings, string separator)
{
return String.Join(separator, strings);
}
}
这将提供与直接调用相同的性能代码(至少从算法复杂度的角度),在某些情况下可能会使代码更易读(取决于上下文), 特别是如果块中的其他代码使用链式函数风格。