Try this
var source = GetTheString();
var reversed = source.Reverse().Select(x => x.ToString()).Aggregate((x,y) => x + "." + y);
EDIT
This solution is definitely aimed at the "clever" end. It's likely much more performant to use a StringBuilder to build up the string. This solution creates many intermediate strings.
EDIT2
There was some debate about the relative speed of the "clever" solution vs. the StringBuilder approach. I wrote up a quick benchmark to measure the approach. As expected, StringBuilder is faster.
- Normal Aggregate (100 elements): 00:00:00.0418640
- WithStringBuilder (100 elements): 00:00:00.0040099
- Normal Aggregate (1000 elements): 00:00:00.3062040
- WithStringBuilder (1000 elements): 00:00:00.0405955
- Normal Aggregate (10000 elements): 00:00:03.0270392
- WithStringBuilder (10000 elements): 00:00:00.4149977
However, whether or not the speed difference is signficant is highly dependent upon where it is actually used in your application.
Code for the benchmark.
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, List<string> inputs, Func<string, string> 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<string> 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());
}
}