这是一个简单的问题.我有一个应用程序,取一个像"13335557777"这样的电话号码,需要反转它并在每个号码之间插入一个点,如下所示:
"7.7.7.7.5.5.5.3.3.3.1."
我知道我可以使用StringBuilder和for循环来反转字符串并插入点,但是有一种聪明的方法可以在LINQ(或其他方式)中执行此操作吗?
注意:为此,我并不真正关心性能或内存分配或其他什么,只是好奇看看如何在LINQ中完成.
试试这个
var source = GetTheString(); var reversed = source.Reverse().Select(x => x.ToString()).Aggregate((x,y) => x + "." + y);
编辑
这个解决方案绝对是针对"聪明"的目标.使用StringBuilder构建字符串可能会更高效.此解决方案创建许多中间字符串
EDIT2
关于"聪明"解决方案与StringBuilder方法的相对速度存在争议.我写了一个快速基准测量方法.正如所料,StringBuilder更快.
正常聚合(100个元素):00:00:00.0418640
WithStringBuilder(100个元素):00:00:00.0040099
正常聚合(1000个元素):00:00:00.3062040
WithStringBuilder(1000个元素):00:00:00.0405955
正常聚合(10000个元素):00:00:03.0270392
WithStringBuilder(10000个元素):00:00:00.4149977
但是,速度差异是否显着在很大程度上取决于应用程序中实际使用的位置.
基准代码.
public static class AggregateUnchanged { public static string Run(string input) { return input .Reverse() .Select(x => x.ToString()) .Aggregate((x, y) => x + "." + y); } } public static class WithStringBuilder { public static string Run(string input) { var builder = new StringBuilder(); foreach (var cur in input.Reverse()) { builder.Append(cur); builder.Append('.'); } if (builder.Length > 0) { builder.Length = builder.Length - 1; } return builder.ToString(); } } class Program { public static void RunAndPrint(string name, Listinputs, Func worker) { // Test case. JIT the code and verify it actually works var test = worker("123456"); if (test != "6.5.4.3.2.1") { throw new InvalidOperationException("Bad algorithm"); } var watch = new Stopwatch(); watch.Start(); foreach (var cur in inputs) { var result = worker(cur); } watch.Stop(); Console.WriteLine("{0} ({2} elements): {1}", name, watch.Elapsed, inputs.Count); } public static string NextInput(Random r) { var len = r.Next(1, 1000); var builder = new StringBuilder(); for (int i = 0; i < len; i++) { builder.Append(r.Next(0, 9)); } return builder.ToString(); } public static void RunAll(List input) { RunAndPrint("Normal Aggregate", input, AggregateUnchanged.Run); RunAndPrint("WithStringBuilder", input, WithStringBuilder.Run); } static void Main(string[] args) { var random = new Random((int)DateTime.Now.Ticks); RunAll(Enumerable.Range(0, 100).Select(_ => NextInput(random)).ToList()); RunAll(Enumerable.Range(0, 1000).Select(_ => NextInput(random)).ToList()); RunAll(Enumerable.Range(0, 10000).Select(_ => NextInput(random)).ToList()); } }