Splitting a string at every character - c#

let's say I have a string "hello world". I would like to end up with " dehllloorw". As I don't find any ready-made solution I thought: I can split the string into a character array, sort it and convert it back to a string.
In perl I can do s// but in .Net I'd have to do a .Split() but there's no overload with no parameters... if I do .Split(null) it seems to split by whitespace and .Split('') won't compile.
how do I do this (I hate to run a loop!)?

Array.Sort("hello world".ToCharArray());
Below is a quick demo console app
class Program
{
static void Main(string[] args)
{
var array = "hello world".ToCharArray();
Array.Sort(array);
Console.WriteLine(new String(array));
Console.ReadLine();
}
}

The characters in a string can be directly used, the string class exposed them as an enumeration - combine that with Linq / OrderBy and you have a one-liner to create the ordered output string:
string myString = "hello world";
string output = new string(myString.OrderBy(x => x).ToArray()); // dehllloorw

You could always do this:
private static string SortStringCharacters(string value)
{
if (value == null)
return null;
return new string(value.ToList().Sort().ToArray());
}

Related

Any way to split two different strings using one c# method?

I have two Strings. For which the output required is as follows.
Input : "Abc (1.23)(12a/b)"
Output : "Abc (1.23)"
Input : "Abc(12a/b)"
Output : "Abc"
I am using C#.
I used string.Split("(")[0]. This gives me output for second but not for first requirement.
I need an equation that works for both. Any help would be appreciated. Thanks.
Here is what you want:
class Program
{
static void Main(string[] args)
{
var result1 = Remove12aSlashb("Abc (1.23)(12a/b)");
var result2 = Remove12aSlashb("Abc(12a/b)");
}
public static string Remove12aSlashb(string str)
{
return str.Replace("(12a/b)", string.Empty);
}
}
It appears that what you are actually trying to do (from your example strings) is to chop off the last set of text in parenthesis. If so, then string.Split("(") can still do it, but then you need to combine the results with a slightly more complicated logic.
Something like this could do it.
public static string RemoveFinalParens(string str) {
var pieces=str.Split("(");
string retString=null;
for (int i=0;i<pieces.Count;i++) {
return+=pieces[i];
if ((i+1)<pieces.Count) {return+="("};
}
return retString;
}

How to change one string from definite position using other string?

I have two strings
string str1 = "Hello World !"; // the position of W character is 6
string str2 = "peace";
//...
string result = "Hello peace !"; // str2 is written to str1 from position 6
Is there a function like this:
string result = str1.Rewrite(str2, 6); // (string, position)
EDITED
This "Hello World !" is just an example, I don't know whether there is "W" character in this string, what I only know are: str1, str2, position (int)
There is not, but you could create one using an extension method.
public static class StringExtensions
{
public static string Rewrite(this string input, string replacement, int index)
{
var output = new System.Text.StringBuilder();
output.Append(input.Substring(0, index));
output.Append(replacement);
output.Append(input.Substring(index + replacement.Length));
return output.ToString();
}
}
Then, the code you posted in your original question would work:
string result = str1.Rewrite(str2, 6); // (string, position)
#danludwigs answer is better from a code understandability perspective, however this version is a tad faster. Your explanation that you are dealing with binary data in string format (wtf bbq btw :) ) does mean that speed might be of the essence. Although using a byte array or something might be better than using a string :)
public static string RewriteChar(this string input, string replacement, int index)
{
// Get the array implementation
var chars = input.ToCharArray();
// Copy the replacement into the new array at given index
// TODO take care of the case of to long string?
replacement.ToCharArray().CopyTo(chars, index);
// Wrap the array in a string represenation
return new string(chars);
}
There is many way to do this...
Because I'm a lazy ass, I would go:
result = str1.Substring(0, 6) + str2 + str1.Substring(12, 2);
or
result = str1.Replace("World", str2);
My advice would be, in Visual Studio, right click on "string" and select "Go To Definition". You will see all the methods available to the string "class".

C# 2.0 function which will return the formatted string

I am using C# 2.0 and I have got below type of strings:
string id = "tcm:481-191820"; or "tcm:481-191820-32"; or "tcm:481-191820-8"; or "tcm:481-191820-128";
The last part of string doesn't matter i.e. (-32,-8,-128), whatever the string is it will render below result.
Now, I need to write one function which will take above string as input. something like below and will output as "tcm:0-481-1"
public static string GetPublicationID(string id)
{
//this function will return as below output
return "tcm:0-481-1"
}
Please suggest!!
If final "-1" is static you could use:
public static string GetPublicationID(string id)
{
int a = 1 + id.IndexOf(':');
string first = id.Substring(0, a);
string second = id.Substring(a, id.IndexOf('-') - a);
return String.Format("{0}0-{1}-1", first, second);
}
or if "-1" is first part of next token, try this
public static string GetPublicationID(string id)
{
int a = 1 + id.IndexOf(':');
string first = id.Substring(0, a);
string second = id.Substring(a, id.IndexOf('-') - a + 2);
return String.Format("{0}0-{1}", first, second);
}
This syntax works even for different length patterns, assuming that your string is
first_part:second_part-anything_else
All you need is:
string.Format("{0}0-{1}", id.Substring(0,4), id.Substring(4,5));
This just uses substring to get the first four characters and then the next five and put them into the format with the 0- in there.
This does assume that your format is a fixed number of characters in each position (which it is in your example). If the string might be abcd:4812... then you will have to modify it slightly to pick up the right length of strings. See Marco's answer for that technique. I'd advise using his if you need the variable length and mine if the lengths stay the same.
Also as an additional note your original function of returning a static string does work for all of those examples you provided. I have assumed there are other numbers visible but if it is only the suffix that changes then you could happily use a static string (at which point declaring a constant or something rather than using a method would probably work better).
Obligatory Regular Expression Answer:
using System.Text.RegularExpressions;
public static string GetPublicationID(string id)
{
Match m = RegEx.Match(#"tcm:([\d]+-[\d]{1})", id);
if(m.Success)
return string.Format("tcm:0-{0}", m.Groups[1].Captures[0].Value.ToString());
else
return string.Empty;
}
Regex regxMatch = new Regex("(?<prefix>tcm:)(?<id>\\d+-\\d)(?<suffix>.)*",RegexOptions.Singleline|RegexOptions.Compiled);
string regxReplace = "${prefix}0-${id}";
string GetPublicationID(string input) {
return regxMatch.Replace(input, regxReplace);
}
string test = "tcm:481-191820-128";
stirng result = GetPublicationID(test);
//result: tcm:0-481-1

Why does TrimStart trims a char more when asked to trim "PRN.NUL"?

Here is the code:
namespace TrimTest
{
class Program
{
static void Main(string[] args)
{
string ToTrim = "PRN.NUL";
Console.WriteLine(ToTrim);
string Trimmed = ToTrim.TrimStart("PRN.".ToCharArray());
Console.WriteLine(Trimmed);
ToTrim = "PRN.AUX";
Console.WriteLine(ToTrim);
Trimmed = ToTrim.TrimStart("PRN.".ToCharArray());
Console.WriteLine(Trimmed);
ToTrim = "AUX.NUL";
Console.WriteLine(ToTrim);
Trimmed = ToTrim.TrimStart("AUX.".ToCharArray());
Console.WriteLine(Trimmed);
}
}
}
The output is like this:
PRN.NUL
UL
PRN.AUX
AUX
AUX.NUL
NUL
As you can see, the TrimStart took out the N from NUL. But it doesn't do that for other strings even if it started with PRN.
I tried with .NET Framework 3.5 and 4.0 and the results are same. Are there any explanation on what causes this behavior?
String.TrimStart works on a character level. What you're doing is you're telling it to remove any "P", "R", "N" or "." characters from the start - therefore the first N after the dot also gets removed.
If you want to remove a certain string from the start of the string, first use StartsWith to ensure it's there and then Substring to take the correct part of the string.
Try this:
string ToTrim = "PRN.NUL";
string Trimmed = ToTrim.TrimStart(".NRP".ToCharArray());
Console.WriteLine(Trimmed);
Notice anything?
#MattiVirkkunen's answer is correct. However, here is a solution, use this extension method instead of RemoveStart method to get your desired results.
public static String RemoveStart(this string s, string text)
{
return s.Substring(s.IndexOf(s) + text.Length, s.Length - text.Length);
}

What should I name this Extension method?

I have written an extension method for string manipulation. I'm confused what should I name it - since this will become part of the base library front-end developers in the team will use. Here's the profile of the class member.
Info: Utility Extension method for String types. Overloads of this method may do the same thing characters other than space [with what supplied in argument]
Purpose: Trims down all intermediate or in-between spaces to single space.
Ex:
string Input = "Hello Token1 Token2 Token3 World! ";
string Output = Input.TrimSpacesInBetween();
//Output will be: "Hello Token1 Token2 Token3 World!"
I have read [in fact I'm reading] the Framework Design guidelines but this seems to be bothering me.
Some options I think..
TrimIntermediate();
TrimInbetween();
Here's the code on Request:
It's recursive..
public static class StringExtensions
{
public static string Collapse(this string str)
{
return str.Collapse(' ');
}
public static string Collapse(this string str, char delimeter)
{
char[] delimeterts = new char[1];
delimeterts[0] = delimeter;
str = str.Trim(delimeterts);
int indexOfFirstDelimeter = str.IndexOf(delimeter);
int indexTracker = indexOfFirstDelimeter + 1;
while (str[indexTracker] == delimeter)
indexTracker++;
str = str.Remove(indexOfFirstDelimeter + 1, indexTracker - indexOfFirstDelimeter - 1);
string prevStr = str.Substring(0, indexOfFirstDelimeter + 1);
string nextPart = str.Substring(indexOfFirstDelimeter + 1);
if (indexOfFirstDelimeter != -1)
nextPart = str.Substring(indexOfFirstDelimeter + 1).Collapse(delimeter);
string retStr = prevStr + nextPart;
return retStr;
}
}
What about CollapseSpaces?
CollapseSpaces is good for just spaces, but to allow for the overloads you might want CollapseDelimiters or CollapseWhitespace if it's really just going to be for various whitespace characters.
Not really an answer, more a comment on your posted code...
You could make the method a lot shorter and more understandable by using a regular expression. (My guess is that it would probably perform better than the recursive string manipulations too, but you would need to benchmark to find out for sure.)
public static class StringExtensions
{
public static string Collapse(this string str)
{
return str.Collapse(' ');
}
public static string Collapse(this string str, char delimiter)
{
str = str.Trim(delimiter);
string delim = delimiter.ToString();
return Regex.Replace(str, Regex.Escape(delim) + "{2,}", delim);
}
}
In ruby I believe they call this squeeze
NormalizeWhitespace ?
This way is more clear that there will be a usable value left after processing.
As other have stated earlier, 'Collapse' sounds somewhat rigorous and might even mean that it can return an empty string.
Try this, it works for me and seems to be a lot less complicated than a recursive solution...
public static class StringExtensions
{
public static string NormalizeWhitespace(this string input, char delim)
{
return System.Text.RegularExpressions.Regex.Replace(input.Trim(delim), "["+delim+"]{2,}", delim.ToString());
}
}
It can be called as such:
Console.WriteLine(input.NormalizeWhitespace(' '));
CollapseExtraWhitespace
PaulaIsBrilliant of course!
How is makeCompact?

Categories

Resources