Task to replace first and last character of two strings - c#

I am doing exercise which provides solutions too however, no explanation on the code in the solution is given and cannot understand the code. Hope I can get help in understanding it
Exercise:
Write a C# program to create a new string from a given string where the first and last characters will change their positions.
Strings:
w3resource
Python
Expected output:
e3resourcw
nythoP
Solution:
public class Exercise16 {
static void Main(string[] args)
{
Console.WriteLine(first_last("w3resource"));
Console.WriteLine(first_last("Python"));
Console.WriteLine(first_last("x"));
}
public static string first_last(string ustr)
{
// code that I don't understand
return ustr.Length > 1
? ustr.Substring(ustr.Length - 1) + ustr.Substring(1, ustr.Length - 2) + ustr.Substring(0, 1) : ustr;
}
}
P.S - I am beginner in C# but not in programming overall

The ? operator is also called the conditional operator in C#. It acts like a miniature if statement letting you express the entire statement in a single expression. In this case it is used to verify that there is at least two characters in the string, otherwise it returns the single character string itself.
As for the Substring statements, consider which characters are being extracted from ustr with each call...
ustr.Substring(ustrLength - 1): extract the last character
ustr.Substring(1, ustr.Length - 2): extract all characters from the second to the second to last
ustr.Substring(0, 1): extract the first character
When concatenated in the order above you can see that the resulting string will start with the final character of the original string, followed by all characters from the second to the second to last, finally followed by the first character.

Basically it says if the length is greater than 1 then execute this:
ustr.Substring(ustr.Length - 1) + ustr.Substring(1, ustr.Length - 2) + ustr.Substring(0, 1)
If not, return this string variable:
ustr
This is an example of Conditional Operator "?:": Microsoft Docs Conditional Operator.
Substring means you get specific range of string character. For examples, you can check Substring Examples.

Related

C# IndexOf in special persian character

in persian/arabic character, some character used optional on top or bottom of other character like ِ َ ّ ُ.
in my example if i use this character, indexOf not found my word. consider that persian/arabic is rtl language.
for example:
منّم => م + ن + ّ + م
C#:
"منّم".IndexOf("من");
return -1
javascript:
var index= ' منّم '.indexOf('من');
console.log(index);
what happened in C#. anyone can explain this?
By passing in StringComparison.Ordinal as an argument to the overloaded String.IndexOf(), you could have also done the following:
"منّم".IndexOf("من", StringComparison.Ordinal); // returns 0
Specifying CompareOptions.Ordinal as an option should work, together with the IndexOf method of CompareInfo.
CompareInfo info = CultureInfo.CurrentCulture.CompareInfo;
string str = "منّم";
Console.WriteLine(info.IndexOf(str, "من", CompareOptions.Ordinal));
Output is 0.
DotNetFiddle if you want to try it yourself.
You should learn about the different methods that .Net uses to compare/match strings.
Best Practices for Using Strings in .NET
Some overloads with default parameters (those that search for a Char
in the string instance) perform an ordinal comparison, whereas others
(those that search for a string in the string instance) are
culture-sensitive. It is difficult to remember which method uses which
default value, and easy to confuse the overloads.
The section String Operations that Use the Invariant Culture gives a short explanation about combining characters.

What's does the dollar sign ($"string") do? [duplicate]

This question already has answers here:
What does $ mean before a string?
(11 answers)
Closed 6 years ago.
I have been looking over some C# exercises in a book and I ran across an example that stumped me. Straight from the book, the output line shows as:
Console.WriteLine($"\n\tYour result is {result}.");
The code works and the double result shows as expected. However, not understanding why the $ is there at the front of the string, I decided to remove it, and now the code outputs the name of the array {result} instead of the contents. The book doesn't explain why the $ is there, unfortunately.
I have been scouring the VB 2015 help and Google, regarding string formatting and Console.WriteLine overload methods. I am not seeing anything that explains why it is what it is. Any advice would be appreciated.
It's the new feature in C# 6 called Interpolated Strings.
The easiest way to understand it is: an interpolated string expression creates a string by replacing the contained expressions with the ToString representations of the expressions' results.
For more details about this, please take a look at MSDN.
Now, think a little bit more about it. Why this feature is great?
For example, you have class Point:
public class Point
{
public int X { get; set; }
public int Y { get; set; }
}
Create 2 instances:
var p1 = new Point { X = 5, Y = 10 };
var p2 = new Point { X = 7, Y = 3 };
Now, you want to output it to the screen. The 2 ways that you usually use:
Console.WriteLine("The area of interest is bounded by (" + p1.X + "," + p1.Y + ") and (" + p2.X + "," + p2.Y + ")");
As you can see, concatenating string like this makes the code hard to read and error-prone. You may use string.Format() to make it nicer:
Console.WriteLine(string.Format("The area of interest is bounded by({0},{1}) and ({2},{3})", p1.X, p1.Y, p2.X, p2.Y));
This creates a new problem:
You have to maintain the number of arguments and index yourself. If the number of arguments and index are not the same, it will generate a runtime error.
For those reasons, we should use new feature:
Console.WriteLine($"The area of interest is bounded by ({p1.X},{p1.Y}) and ({p2.X},{p2.Y})");
The compiler now maintains the placeholders for you so you don’t have to worry about indexing the right argument because you simply place it right there in the string.
For the full post, please read this blog.
String Interpolation
is a concept that languages like Perl have had for quite a while, and
now we’ll get this ability in C# as well. In String Interpolation, we
simply prefix the string with a $ (much like we use the # for verbatim
strings). Then, we simply surround the expressions we want to
interpolate with curly braces (i.e. { and }):
It looks a lot like the String.Format() placeholders, but instead of an index, it is the expression itself inside the curly braces. In fact, it shouldn’t be a surprise that it looks like String.Format() because that’s really all it is – syntactical sugar that the compiler treats like String.Format() behind the scenes.
A great part is, the compiler now maintains the placeholders for you so you don’t have to worry about indexing the right argument because you simply place it right there in the string.
C# string interpolation is a method of concatenating,formatting and manipulating strings. This feature was introduced in C# 6.0. Using string interpolation, we can use objects and expressions as a part of the string interpolation operation.
Syntax of string interpolation starts with a ‘$’ symbol and expressions are defined within a bracket {} using the following syntax.
{<interpolatedExpression>[,<alignment>][:<formatString>]}
Where:
interpolatedExpression - The expression that produces a result to be formatted
alignment - The constant expression whose value defines the minimum number of characters in the string representation of the
result of the interpolated expression. If positive, the string
representation is right-aligned; if negative, it's left-aligned.
formatString - A format string that is supported by the type of the expression result.
The following code example concatenates a string where an object, author as a part of the string interpolation.
string author = "Mohit";
string hello = $"Hello {author} !";
Console.WriteLine(hello); // Hello Mohit !
Read more on C#/.NET Little Wonders: String Interpolation in C# 6

String.Contains and String.LastIndexOf C# return different result?

I have this problem where String.Contains returns true and String.LastIndexOf returns -1. Could someone explain to me what happened? I am using .NET 4.5.
static void Main(string[] args)
{
String wikiPageUrl = #"http://it.wikipedia.org/wiki/ʿAbd_Allāh_al-Sallāl";
if (wikiPageUrl.Contains("wikipedia.org/wiki/"))
{
int i = wikiPageUrl.LastIndexOf("wikipedia.org/wiki/");
Console.WriteLine(i);
}
}
While #sa_ddam213's answer definitely fixes the problem, it might help to understand exactly what's going on with this particular string.
If you try the example with other "special characters," the problem isn't exhibited. For example, the following strings work as expected:
string url1 = #"http://it.wikipedia.org/wiki/»Abd_Allāh_al-Sallāl";
Console.WriteLine(url1.LastIndexOf("it.wikipedia.org/wiki/")); // 7
string url2 = #"http://it.wikipedia.org/wiki/~Abd_Allāh_al-Sallāl";
Console.WriteLine(url2.LastIndexOf("it.wikipedia.org/wiki/")); // 7
The character in question, "ʿ", is called a spacing modifier letter1. A spacing modifier letter doesn't stand on its own, but modifies the previous character in the string, this case a "/". Another way to put this is that it doesn't take up its own space when rendered.
LastIndexOf, when called with no StringComparison argument, compares strings using the current culture.
When strings are compared in a culture-sensitive manner, the "/" and "ʿ" characters are not seen as two distinct characters--they're processed into one character, which does not match the parameter passed in to LastIndexOf.
When you pass in StringComparison.Ordinal to LastIndexOf, the characters are treated as distinct, due to the nature of Ordinal comparison.
Another way to make this work would be to use CompareInfo.LastIndexOf and supply the CompareOptions.IgnoreNonSpace option:
Console.WriteLine(
CultureInfo.CurrentCulture.CompareInfo.LastIndexOf(
wikiPageUrl, #"it.wikipedia.org/wiki/", CompareOptions.IgnoreNonSpace));
// 7
Here we're saying that we don't want combining characters included in our string comparison.
As a sidenote, this means that #Partha's answer and #Noctis' answer only work because the character is being applied to a character that doesn't appear in the search string that's passed to LastIndexOf.
Contrast this with the Contains method, which by default performs an Ordinal (case sensitive and culture insensitive) comparison. This explains why Contains returns true and LastIndexOf returns false.
For a fantastic overview of how strings should be manipulated in the .NET framework, check out this article.
1: Is this different than a combining character or is it a type of combining character? would appreciate if someone would clear that up for me.
Try using StringComparison.Ordinal
This will compare the string by evaluating the numeric values of the corresponding chars in each string, this should work with the special chars you have in that example string
string wikiPageUrl = #"http://it.wikipedia.org/wiki/ʿAbd_Allāh_al-Sallāl";
int i = wikiPageUrl.LastIndexOf("http://it.wikipedia.org/wiki/", StringComparison.Ordinal);
// returns 0;
The thing is C# lastindexof looks from behind.
And wikipedia.org/wiki/ is followed by ' which it takes as escape sequence. So either remove ' after wiki/ or have an # there too.
The following syntax will work( anyone )
string wikiPageUrl = #"http://it.wikipedia.org/wiki/Abd_Allāh_al-Sallāl";
string wikiPageUrl = #"http://it.wikipedia.org/wiki/#ʿAbd_Allāh_al-Sallāl";
int i = wikiPageUrl.LastIndexOf("wikipedia.org/wiki");
All 3 works
If you want a generalized solution for this problem replace ' with #' in your string before you perform any operations.
the ' characters throws it off.
This should work, when you escape the ' as \':
wikiPageUrl = #"http://it.wikipedia.org/wiki/\'Abd_Allāh_al-Sallāl";
if (wikiPageUrl.Contains("wikipedia.org/wiki/"))
{
"contains".Dump();
int i = wikiPageUrl.LastIndexOf("wikipedia.org/wiki/");
Console.WriteLine(i);
}
figure out what you want to do (remove the ', escape it, or dig deeper :) ).

Modifying string.Substring

9 times out of 10, when I want to use the Substring() method on a string, it's because I want to shave some characters off the END of the string, not the start. While the default Substring does have support for this, it does so by taking a second parameter which is the length of the desired string, rather than the endpoint. This means if I consistently want to shave off N characters off of a series of strings of differing length, I have to do an extra step, which can result in a good deal more code. Take for example:
//Shaving the first N chars
string trimmed = foo.bar.widget.GetType().Name.Substring(N);
vs.
//Shaving the last N chars
string trimmed = foo.bar.widget.GetType().Name.Substring(0, foo.bar.widget.GetType().Name.Length - N);
or maybe to save the extra function call, use a second line:
string name = foo.bar.widget.GetType().Name;
string trimmed = name.Substring(0, name.Length - N);
Either way, you're basically doubling the amount of code necessary to shave characters off the end of the string rather than the beginning. My modification would be simple. If you pass a negative N (which would otherwise be meaningless), it would shave -N characters off the end of the string instead of the beginning. I can already code this up with an extension method:
public static string MySubstring(this string str, int val)
{
return (val > 0) ? str.Substring(val) : str.Substring(0, str.Length + val);
}
And then when I want to shave off the final N chars, I just do:
string trimmed = foo.bar.widget.GetType().Name.MySubstring(-N);
Short and sweet, just like shaving off the beginning characters. My question is - would it be possible to override the behavior of the default Substring() function so that I can do this without having to use my own unique name for the function? It's not like it would invalidate any existing code, because previously there was no reason to pass it a negative number, and doing so would simply throw an exception and crash. This is just one of those simple no-nonsense features that feels like it should've been part of the implementation to begin with.
According to C# documentation, you can use extension methods to extend a class or interface, but not to override them. An extension method with the same name and signature as an interface or class method will never be called. So the answer is "No".
Arguably, this is a good thing™, because otherwise your code would become a nightmare to read to someone not familiar with your extension.
Note: str.Substring(0, str.Length + val); can be replaced with str.Remove(str.Length + val)
You can't override a method on string in the strict sense using extension methods, as the compiler will always choose an instance method over an extension method with the same signature when compiling a method call. However, you can achieve something close to what you want using named arguments. This should also help avoid readability issues. Here's an example
public static string Substring(this string #this, int trimFromEnd)
{
return #this.Substring(0, #this.Length - trimFromEnd);
}
// if you do
"abc".Substring(1) -> returns "bc"
// if you do
"abc".Substring(trimFromEnd: 1) -> returns "ab"
Personally, I find this a bit more readable than Substring(-1) or just Substring(varName), where varName happens to be negative.

Getting substring for string

I have a string of the format
[00:26:19] Completed 80000 out of 500000 steps (16%)
from which I want to get the 16 part.
Should I search for ( and then get the % and get the portion in between, or would it be wiser to set up a regex query?
RegEx is probably going to be the trend, but I don't see a good reason for it, personally.
That being said, this should work:
String s = "[00:26:19] Completed 80000 out of 500000 steps (16%)";
Int32 start = s.LastIndexOf('(') + 1;
Console.WriteLine(s.Substring(start,s.LastIndexOf('%')-start));
And you can Convert.ToInt32() if you feel it necessary.
I would use a regular expression like this:
([^%]+)%\)$
This expression would allow non-numeric data to be captured - if you are certain that the text within the parenthesis and just to the left of the percentage will always be a number you can simplify the expression to this:
(\d+)%\)$
Another Fast way is...
string s = "[00:26:19] Completed 80000 out of 500000 steps (16%)";
string res = s.Split("(%".ToCharArray())[1];
this assumes we will only see '(' and '%' once in the string
It depends on how variable you expect the input string (the "haystack") to be, and how variable you expect your target pattern (the "needle") to be. Regexes are extremely useful for describing a whole class of needles in a largely unknown haystack, but they're not the right tool for input that's in a very static format.
If you know your string will always be something like:
"[A:B:C] Completed D out of E steps (F%)"
where 1) A-F are the only variable portions, and 2) A-F are always numeric, then all you need is a little string manipulation:
int GetPercentage(string str)
{
return int.Parse(
str.Substring(
str.IndexOf('(') + 1,
str.IndexOf('%') - str.IndexOf('(')
)
);
}
The key question here is: "Are the presence of ( and % sufficient to indicate the substring I'm trying to capture?" That is, will they only occur in that one position? If the rest of the haystack might contain ( or % somewhere, I'd use regex:
#"(?<=\()\d+(?=%\)))$"

Categories

Resources