How do I not String.Remove anything? - c#

I have a string that may or may not need truncating. I'm passing two non-negative integers as arguments to my program. The first one is supposed to tell the program how many characters need to be removed from the beginning of the string, and the second one tells it how many characters to remove from the end. Is there a way to do it so that zeroes work properly as input, the meaning of the code is self-evident and there are no silly conditional statements like if (removefirst != 0).
string.Remove(0, removefirst) needs the conditional statement because the first argument needs to be strictly less than the second one, says the exception message. Is there a way to do it more prettily?

Math + use Substring()?
var result = str.Substring(firstNumber, str.Length - (firstNumber + secondNumber));
DotNetFiddle Example
string yourstring = "asdf";
string result;
int firstNumber = 0;
int secondNumber = 0;
Console.WriteLine(yourstring);
result = yourstring.Substring(firstNumber, yourstring.Length - (firstNumber+secondNumber));
Console.WriteLine(result);
firstNumber = 1;
secondNumber = 1;
result = yourstring.Substring(firstNumber, yourstring.Length - (firstNumber+secondNumber));
Console.WriteLine(result);
Results
asdf
asdf
sd

Related

how to add a sign between each letter in a string in C#?

I have a task, in which i have to write a function called accum, which transforms given string into something like this:
Accumul.Accum("abcd"); // "A-Bb-Ccc-Dddd"
Accumul.Accum("RqaEzty"); // "R-Qq-Aaa-Eeee-Zzzzz-Tttttt-Yyyyyyy"
Accumul.Accum("cwAt"); // "C-Ww-Aaa-Tttt"
So far I only converted each letter to uppercase and... Now that I am writing about it, I think it could be easier for me to - firstly multiply the number of each letter and then add a dash there... Okay, well let's say I already multiplied the number of them(I will deal with it later) and now I need to add the dash. I tried several manners to solve this, including: for and foreach(and now that I think of it, I can't use foreach if I want to add a dash after multiplying the letters) with String.Join, String.Insert or something called StringBuilder with Append(which I don't exactly understand) and it does nothing to the string.
One of those loops that I tried was:
for (int letter = 0; letter < s.Length-1; letter += 2) {
if (letter % 2 == 0) s.Replace("", "-");
}
and
for (int letter = 0; letter < s.Length; letter++) {
return String.Join(s, "-");
}
The second one returns "unreachable code" error. What am I doing wrong here, that it does nothing to the string(after uppercase convertion)? Also, is there any method to copy each letter, in order to increase the number of them?
As you say string.join can be used as long as an enumerable is created instead of a foreach. Since the string itself is enumerable, you can use the Linq select overload which includes an index:
var input = "abcd";
var res = string.Join("-", input.Select((c,i) => Char.ToUpper(c) + new string(Char.ToLower(c),i)));
(Assuming each char is unique or can be used. e.g. "aab" would become "A-Aa-Bbb")
Explanation:
The Select extension method takes a lambda function as parameter with c being a char and i the index. The lambda returns an uppercase version of the char (c) folowed by a string of the lowercase char of the index length (new string(char,length)), (which is an empty string for the first index). Finally the string.join concatenates the resulting enumeration with a - between each element.
Use this code.
string result = String.Empty;
for (int i = 0; i < s.Length; i++)
{
char c = s[i];
result += char.ToUpper(c);
result += new String(char.ToLower(c), i);
if (i < s.Length - 1)
{
result += "-";
}
}
It will be better to use StringBuilder instead of strings concatenation, but this code can be a bit more clear.
Strings are immutable, which means that you cannot modify them once you created them. It means that Replace function return a new string that you need to capture somehow:
s = s.Replace("x", "-");
you currently are not assigning the result of the Replace method anywhere, that's why you don't see any results
For the future, the best way to approach problems like this one is not to search for the code snippet, but write down step by step algorithm of how you can achieve the expected result in plain English or some other pseudo code, e.g.
Given I have input string 'abcd' which should turn into output string 'A-Bb-Ccc-Dddd'.
Copy first character 'a' from the input to Buffer.
Store the index of the character to Index.
If Buffer has only one character make it Upper Case.
If Index is greater then 1 trail Buffer with Index-1 lower case characters.
Append dash '-' to the Buffer.
Copy Buffer content to Output and clear Buffer.
Copy second character 'b' from the input to Buffer.
...
etc.
Aha moment often happens on the third iteration. Hope it helps! :)

Is there a fast extraction of specific value located inside tags in a slice from a list of strings possible?

I'm using a 2 step regex to extract the value of the first occurance of a specific marker inside a list of strings:
Regex regexComplete = new Regex(
#"MyNumberMarker"
+ #"[\d]+"
+ #"[\s]+Endmarker"
);
Regex regexOnlyNumber = new Regex(
#"MyNumberMarker"
+ #"[\d]+"
);
int indexmyNumber = eintraegeListe.FindIndex(
5,
10000,
x => regexComplete.IsMatch(x)
);
if (indexmyNumber >= 0)
{
int myNumber = 0;
string myNumberString = regexOnlyNumber.Match(regexComplete.Match(eintraegeListe[indexmyNumber]).Value).Value;
myNumberString = myNumberString.Replace("MyNumberMarker", "").Replace("\n", "").Replace("\r", "").Trim();
if (Int32.TryParse(myNumberString, out myNumber))
{
return myNumber;
}
}
As one can see the value I really want is located between "MyNumberMarker" and "Endmarker". It is in a specific part of the list which I search through with the findIndex command. Then I use regex to extract the complete value + tag and reduce it to "just" the begin tag and the value and then manually cut away the begin tag and all could be white spaces (including \n and \r).
Now this works quite fine as intended but if I do this a couple of thousand times it is quite slow in the end. Thus my question.
Is there any better (faster) way to do this?
As a note: eintraegeListe can have between 100 and 30000 entries.
For example if I have the following small list:
[0]This is a test
[1]22.09.2015 01:00:00
[2]Until 22.09.2015 03:00:00
[3]................................
[4]................................
[5]........ TESTDATA
[6]...............................
[7]................................
[8]MyNumberMarker519 Endmarker
[9]This is a small
[10]Slice of Test data with
[11]520 - 1 as data.
I would expect 519 to be returned.
Since you are returning a single item, the performance of code past FindIndex is irrelevant: it is executed only once, and it takes a single string, so it should complete in microseconds on any modern hardware.
The code that takes the bulk of CPU is in x => regexComplete.IsMatch(x) call. You can tell that this code is returning false most of the time, because the loop is over the first time it returns true.
This means that you should be optimizing for the negative case, i.e. returning false as soon as you can. One way to achieve this would be to look for "MyNumberMarker" before employing regex. If there is no marker, return false right away; otherwise, fall back on using the regex, and start from the position where you found the marker:
int indexmyNumber = eintraegeListe.FindIndex(
5,
10000,
x => {
// Scan the string for the marker in non-regex mode
int pos = x.IndexOf("MyNumberMarker", StringComparison.Ordinal);
// If the marker is not there, do not bother with regex, and return false
return pos < 0
? false
// Only if the marker is there, check the match with regex.
: regexComplete.IsMatch(x, pos);
}
);
You can actually merge the two regexps into 1 containing a capturing group that will let you access the sequence of digits directly via the group name (here, "number").
Regex regexComplete = new Regex(#"MyNumberMarker(?<number>\d+)\s+Endmarker");
Now, you do not need regexOnlyNumber.
Then, you can add a non-regex condition as in the other answer. Maybe this will be enough (the .Contains will be executed first and the whole expression should evaluate to false if the first condition is not met - see "short-circuit" evaluation) (IndexOf with StringComparison.Ordinal looks preferable anyway):
int indexmyNumber = eintraegeListe.FindIndex(5, 10000, x => x.Contains("MyNumberMarker") && regexComplete.IsMatch(x));
And then:
if (indexmyNumber >= 0)
{
int myNumber = 0;
string myNumberString = regexComplete.Match(eintraegeListe[indexmyNumber]).Groups["number"].Value;
if (Int32.TryParse(myNumberString, out myNumber))
{
return myNumber;
}
}

How to escape variables in C#?

I want to know if what wrong is with
this peace of code? I mean how to escape
to variables from strings (in C#)? (if I had correctly understood what escaping is.)
int i;
string s;
for(i=0;i<10;i++)
{
s="\u00A"+i;
Console.WriteLine(s);
}
(Actually I want the program to write
a sereies of unicode chatacters to make a uncode table for example 00A9=® and 00A5=¥.
Or in general I want to use a variable after backslash)
To make it simple:
string a,b;
a="t";
b="n";
Console.WriteLine("Hi\{0}All\{1}",a,b);
Which I want to type a tab and insert a new line (I know it's possible to write \n and \t in WriteLine directly but I assume we want to get the special chracter from user)
Thanks in advance. ☺
int i;
string x;
for(i=0;i<10;i++)
{
x= #"\u00A" + i; //if you want the backslash
// without # it's x= "\\u00A"+i; //so the backslash is escaped
Console.WriteLine(x);
}
Edit
for (int i = 0; i < 10; i++)
{
Console.WriteLine(
char
.ConvertFromUtf32(
int.Parse("00A"+ i, System.Globalization.NumberStyles.HexNumber)));
}
The only thing you can do about the other problem:
string a,b;
a="\t";
b="\n";
Console.WriteLine("Hi{0}All{1}",a,b);
Unicode escape sequence requires 4 digits:
for(var i = 0; i < 10; i++)
{
var x="\u000A"+i; // notice 3 zeros
Console.WriteLine(x);
}
Notes
usually you'd use "\n" for new line (or even Environemnt.NewLine) like Console.Write("\n" + i);
adding integer (or any other value) to string causes automatic call to .ToString so you can add any object to string. Often it is better to use String.Format("\n {0}", i); instead of + to provide more flexible/readable formatting (adding many strings - have better methods - search).
if you are looking for writing out characters with code to particular integer value (like 32 is space) you should cast it to char: x="\u000A"+(char)i - also you should pick printable range (like 32-42).

C# string toCharArray out of range exception

I came across this issue while I was fixing someone else's code. apparently they were trying to control digits after the decimal point like this:
public static bool check_count(double d)
{
string str = d.ToString();
bool b = true;
if (str.IndexOf('.'))
{
char[] ch = str.ToCharArray(str.IndexOf('.'), str.Length - 1);
if (ch.Length > 5)
b = false;
}
return b;
}
I wasn't going to bother myself fixing that since I'm replacing it with regular expressions but it made me curious. the ToCharArray is throwing ArgumentOutOfRangeException when it shouldn't(?!)
let's say
string str = "20.222";
Console.WriteLine(str);
int index = str.IndexOf('.');
if (index > -1)
{
Console.WriteLine(index);
Console.WriteLine(str.Length-1);
char[] ch = str.ToCharArray(index, str.Length - 1);
}
output:
20.222
2
5
live demo [here]
so the string is 6 chars long and the start index is 2, what argument is out of what range?
I feel lost in this .. any ideas?
thanks
what argument is out of what range?
Well, I'd expect the exception to tell you that - but I'd also expect it to be the second argument. (EDIT: Looking at the exception you actually get, even from .NET, it's actually blaming the first argument. Admittedly it's the combination of the first and second arguments which is invalid, but it's more sensible to blame the second one in this case, as the first one is valid on its own.)
Look at the documentation - the second argument is the length, not the end index. So I suspect you want something like:
char[] ch = str.ToCharArray(index, str.Length - index);
Or to get just the digits after the .:
char[] ch = str.ToCharArray(index + 1, str.Length - index - 1);

MVC - Controller - Make a Simple Math Calculation - Variable + 1

I have a little problem to make a simple math calculation in the controller.
what I try to do is add +1 to a number of a variable.
Here is an example for you to understand better what I try to do:
var a= formcollection["Id_this"];
var next = a + 1;
Note: the value of "Id_this" is "1".
The result I need for the variable next is 2
My problem is that the result of the variable next is "12".
a is a string. Adding a number to a string results in the number being converted to a string and being concatenated.
To make it work, you first need to convert a to a number:
var next = Convert.ToInt32(a) + 1;
Reason is you are doing string concatenation. Try this safe approach:
int number;
int next = 0;
if(Int32.TryParse(formcollection["Id_this"], out number))
{
next = number + 1;
}
else
{
//formcollection["Id_this"] is not a number
}
like this :
var next = int.Parse(a) + 1;

Categories

Resources