Here's a simple problem. I have an application that takes a phone number like "13335557777", and needs to reverse it and insert a dot between each number, like this:
"7.7.7.7.5.5.5.3.3.3.1."
I know I can do this with a StringBuilder and a for-loop to reverse the string and insert the dots, but is there a clever way to do this in LINQ (or some other way)?
Note: for this, I'm not really concerned with performance or memory allocation or whatever, just curious to see how this would be done in LINQ.
C programming language is a machine-independent programming language that is mainly used to create many types of applications and operating systems such as Windows, and other complicated programs such as the Oracle database, Git, Python interpreter, and games and is considered a programming foundation in the process of ...
In the real sense it has no meaning or full form. It was developed by Dennis Ritchie and Ken Thompson at AT&T bell Lab. First, they used to call it as B language then later they made some improvement into it and renamed it as C and its superscript as C++ which was invented by Dr.
What is C? C is a general-purpose programming language created by Dennis Ritchie at the Bell Laboratories in 1972. It is a very popular language, despite being old. C is strongly associated with UNIX, as it was developed to write the UNIX operating system.
C is a general-purpose language that most programmers learn before moving on to more complex languages. From Unix and Windows to Tic Tac Toe and Photoshop, several of the most commonly used applications today have been built on C. It is easy to learn because: A simple syntax with only 32 keywords.
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.
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());
}
}
The benefit of this one is that String.Join is going to be cheaper than ".Aggregate((x,y) => x + "." + y)".
var target = string.Join(".", source.Reverse().Select(c => c.ToString()).ToArray());
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With