C# Switch-case string end with - c#

Is there any way to make a case condition in a switch statement where you say if a string end with something?
switch (Pac.Sku)
{
case "A":
pacVM.Sucursal = "Managua";
break;
case "B":
pacVM.Sucursal = "Masaya";
break;
case "C":
pacVM.Sucursal = "Leon";
break;
default:
pacVM.Sucursal = "N/A";
break;
}

Get the last character of the string, and switch over the result:
switch (Pac.Sku.Last())
{
case 'A':
pacVM.Sucursal = "Managua";
break;
case 'B':
pacVM.Sucursal = "Masaya";
break;
case 'C':
pacVM.Sucursal = "Leon";
break;
default:
pacVM.Sucursal = "N/A";
break;
}
If the string could be null or empty use something like this function instead of Last(). This function returns null if the string is null, null if the string is empty, and the last character of the string if it is not null or empty:
char? GetLast(string s)
{
return s?.Length > 0 ? s.Last() : (char?)null;
}
Switch:
switch(GetLast(Pac.Sku))

You can
use pattern matching feature of C# 7.0 to achieve this. Here is a very basic example:
var t = "blah";
switch (t)
{
case var a when t.EndsWith("bl"):
Console.WriteLine("I'm not here");
break;
case var b when t.EndsWith("ah"):
Console.WriteLine("I'm here");
break;
}

You can get creative with a Func<string, string>[] like this:
Func<string, string>[] cases = new Func<string, string>[]
{
x => x.EndsWith("A") ? "Managua" : null,
x => x.EndsWith("B") ? "Masaya" : null,
x => x.EndsWith("C") ? "Leon" : null,
x => "N/A",
};
Func<string, string> #switch = cases.Aggregate((x, y) => z => x(z) ?? y(z));
string result = #switch(Pac.Sku);
I have tested this with sample input that matches each of the cases and it works just fine.
One significant advantage with this approach is that you can build the Func<string, string>[] at run-time. Nice for creating configurable solutions.
You're also not limited to just using EndsWith - any condition can be used that suits the purpose.

I think it's not a way!
You can only use the if-else
if (Pac.Sku.EndsWith("A") )
{
pacVM.Sucursal= "Managua";
}
else if (Pac.Sku.EndsWith("B"))
{
pacVM.Sucursal= "Masaya";
}
else if (Pac.Sku.EndsWith("C"))
{
pacVM.Sucursal= "Leon";
}
else
{
pacVM.Sucursal= "N/A";
}

Related

How to get the month name using Dictionary in C#?

I have implemented the first three letters of the month to full name of the month in get Full Month function it is returned based on three letters .
But how to implemented in Dictionary concept Any one simplify modify this code given below code:
**public static string getFullMonth(string mthname)
{
string Mthname = "";
switch (mthname.ToUpper())
{
case "JAN":
Mthname ="January";
break;
case "FEB":
Mthname = "February";
break;
case "MAR":
Mthname = "March";
break;
case "APR:":
Mthname = "April";
break;
case "MAY":
Mthname = "May";
break;
case "JUN":
Mthname = "June";
break;
case "JUL":
Mthname = "July";
break;
case "AUG":
Mthname = "August";
break;
case "SEP":
Mthname = "September";
break;
case "OCT":
Mthname = "October";
break;
case "NOV":
Mthname = "November";
break;
case "DEC":
Mthname = "December";
break;
default:
Console.WriteLine("Invalid grade");
break;
}
return Mthname;
}**
simplify this code given below code
Yes, don't use a dictionary at all:
public static string GetFullMonth(string englishShortMonthName)
{
CultureInfo englishCulture = CultureInfo.InvariantCulture;
if (DateTime.TryParseExact(englishShortMonthName, "MMM", englishCulture, DateTimeStyles.None, out DateTime dt))
return dt.ToString("MMMM", englishCulture);
return englishShortMonthName;
}
Read about the month ("M", "m") format specifier
Look up Dictionary syntax. Ultimately you're looking for something like this:
var monthNames = new Dictionary<string, string>
{
{ "JAN", "January" },
{ "FEB", "February" },
...
}
Please find complete solution
public static string getFullMonth(string mthname)
{
var monthNames = new Dictionary<string, string>
{
{ "JAN", "January" },
{ "FEB", "February" },
...
}
return monthNames[mthname];
}
But above code looks weird So You should create dictionary globally and initialize in constructor.
Add only below line in getFullMonth function.
return monthNames[mthname];

How to get all the values within multiple curly braces

How do I split the following into an array of strings within the curly braces?
i have tried regex, but the pattern is thrown off because of the new line
string script = #"{
ABC
DEF
}
{
GHI
LMN
}
{
QWE
ERT
}
"
return an array of with the new line intact
["ABC\nDEF", "GHI\nLMN", "QWE\nERT"]
Hej i hope i got you right.
I know it is not the nices solution but it is something.
using System.Collections.Generic;
using System.Linq;
namespace ConsoleApp6
{
internal class Program
{
private enum Token
{
Open,
Close,
Char,
UnKnowChar,
Space,
NewLine,
}
private static void Main(string[] args)
{
var text = #"{
ABC
DEF
}
{
GHI
LMN
}
{
QWE
ERT
}
";
var strings = Parse(text).ToArray();
}
private static IEnumerable<string> Parse(string text)
{
var strings = new List<string>();
var tokens = GetTokens(text);
var opens = tokens.Select((token, index) => new {token, index})
.Where(list => list.token == Token.Open).ToList();
foreach (var open in opens)
{
var index = tokens.FindIndex(open.index, token => token == Token.Close);
var substring = text.Substring(open.index + 1, index - open.index - 1);
var trim = substring.Trim('\r', '\n', ' ');
strings.Add(trim.Replace(' '.ToString(), string.Empty));
}
return strings;
}
private static List<Token> GetTokens(string text)
{
var tokens = new List<Token>();
foreach (var _char in text)
switch (_char)
{
case ' ':
tokens.Add(Token.Space);
break;
case '\r':
case '\n':
tokens.Add(Token.NewLine);
break;
case '{':
tokens.Add(Token.Open);
break;
case '}':
tokens.Add(Token.Close);
break;
case 'A':
case 'B':
case 'C':
case 'D':
case 'E':
case 'F':
case 'G':
case 'H':
case 'I':
case 'J':
case 'K':
case 'L':
case 'M':
case 'N':
case 'O':
case 'P':
case 'Q':
case 'R':
case 'S':
case 'T':
case 'U':
case 'V':
case 'W':
case 'X':
case 'Y':
case 'Z':
tokens.Add(Token.Char);
break;
default:
tokens.Add(Token.UnKnowChar);
break;
}
return tokens;
}
}
}
Have a nice day.
Here's pretty much the same answer as h3e, except without adding the extra Tokens class and enum. We can just treat the string as an array of characters, get the indexes of all the opening and closing braces, and then grab the substrings from between them:
private static IEnumerable<string> GetItems(string text)
{
var items = new List<string>();
var openBraceIndexes = text.Select((chr, index) => new { chr = chr, index })
.Where(item => item.chr == '{').ToList();
var closeBraceIndexes = text.Select((chr, index) => new { chr, index })
.Where(item => item.chr == '}').ToList();
if (openBraceIndexes.Count != closeBraceIndexes.Count)
{
throw new FormatException("text contains an unequal number of open and close braces");
}
for (int i = 0; i < openBraceIndexes.Count; i++)
{
var startIndex = openBraceIndexes[i].index + 1;
var length = closeBraceIndexes[i].index - startIndex;
items.Add(text.Substring(startIndex, length).Trim());
}
return items;
}

How to store outcome of switch statement into an object in c#

Is it possible to create an object that stores the outcome of the switch statement in c#? Because my end goal is to compare the object in an if statement, and if that's true then it will print a writeline.
switch (results)
{
case 1:
checkingWriter.WriteLine("text");
break;
case 0:
checkingWriter.WriteLine("text");
error_Found = true;
break;
case -1:
checkingWriter.WriteLine("text");
error_Found = true;
break;
case -2:
checkingWriter.WriteLine("text");
error_Found = true;
break;
case -3:
checkingWriter.WriteLine("text");
error_Found = true;
break;
}
You are mixing both side effects and the computation of a value; this is a bad code smell and you might consider separating that logic.
To address your specific question: at this time there is no easy way to get a value computed by a particular switch case section out of the switch. However, this feature has been proposed for C# 8.0, so it seems likely that you'll get some version of this. See the link below for the proposal:
https://neelbhatt.com/2018/05/19/c-8-0-expected-features-part-iii-switch-statments/
Yes, something like (but very basic since we do not have any details):
var objectToCheck = ...; // Some initialized value or null
switch(...)
{
case ...:
objectToCheck = ...
break;
case ...:
objectToCheck = ...
break;
...
default:
Error handling
}
if (objectToCheck ==/.Equals(...) ) // Check object
create variable before switch statement begins, store the switch case result in variable. After switch ends, use the variable in the if condition.
var result = null;
switch (caseSwitch)
{
case 1:
result = fn1();
break;
case 2:
result = fn2();
break;
default:
Console.WriteLine("Default case");
break;
}
if(result == 'your condition')
do something
There are not enough details but may this works, or give you a new idea:
public class Foo
{
public static bool operator !=(Foo foo1, int results){
return results <= 0;
}
public static bool operator ==(Foo foo1, int results){
switch(results)
{
case 1:
Console.WriteLine("All gones good");
return false;
case 0:
Console.WriteLine("Nothing happend");
break;
case -1:
Console.WriteLine("Error 183");
break;
case -2:
Console.WriteLine("Fatal Error");
break;
case -3:
Console.WriteLine("The user doesn't exists");
break;
default:
return false;
}
return true;
}
}
And when you use it:
public static void Main()
{
Foo foo = new Foo();
int results = 0;
// makes some logic that fills results
if(foo == results){
Console.WriteLine("Do Something Custom Here");
}
results = -1;
if(foo == results){
Console.WriteLine("Do Another Something Custom Here");
}
}
It will give you in console something like this:
//Nothing happend
//Do Something Custom Here
//Error 183
//Do Another Something Custom Here

Passing a parameter into an anonymous Func

The following code outputs bee:
var str = "B";
var env = new Func<string>(() => {
switch (str)
{
case "A":
return "aye";
case "B":
return "bee";
default:
return "see";
}
}).Invoke();
Console.WriteLine(env);
How can I pass the str variable as a parameter to the anonymous function? The closest I can get is this:
var str = "B";
Func<string, string> env = a => {
switch (a)
{
case "A":
return "aye";
case "B":
return "bee";
default:
return "see";
}
};
Console.WriteLine(env(str));
But that is not anonymous, as it is named env.
Is it possible to use the first form and still pass in a parameter?

is there any way to simplify this double conditional clauses structure?

for example
if (x=="A)
switch (y)
{
case "1": Do1();break;
case "2": Do2();break;
case "3": Do3();break;
}
else if (x=="B")
switch (y)
{
case "1": Do4();break;
case "2": Do5();break;
case "3": Do6();break;
}
else
switch (y)
{
case "1": Do7();break;
case "2": Do8();break;
case "3": Do9();break;
}
I wish I could do the following, however it has many redundant checks.
if (x=="A" && y=="1")
Do1();
else if (x=="A" && y=="2")
Do2();
else if (x=="A" && y=="3")
Do3();
else if (x=="B" && y=="1")
Do4();
else if (x=="B" && y=="2")
Do5();
else if (x=="B" && y=="3")
Do6();
else if (x=="C" && y=="1")
Do7();
else if (x=="C" && y=="2")
Do8();
else if (x=="C" && y=="3")
Do9();
Suggestion to introduce OOPS is really great, please do not ignore that comment. For time being you can write your code like this.
var combinedText = x+y;
switch(combinedText)
{
case "A1": Do1(); break;
case "A2": Do2(); break;
case "A3": Do3(); break;
case "B1": Do4(); break;
case "B2": Do5(); break;
case "B3": Do6(); break;
case "C1": Do7(); break;
case "C2": Do8(); break;
case "C3": Do9(); break;
}
Your code currently has two responsibilities - deciding what set of methods to execute (varible x) and deciding which exact method to execute (varible y). Simplest option to make code much more clear - split this responsibilities and extract methods, that will decide which method from set of methods to call
switch (x)
{
case "A": DoA(y); break;
case "B": DoB(y); break;
default:
DoDefault(y); break;
}
Now your caller code is simple. And here is one of DoX methods:
private void DoA(string y)
{
switch (y)
{
case "1": Do1(); break;
case "2": Do2(); break;
case "3": Do3(); break;
}
}
Other option is to make .net to decide which set of methods to call, by using polymorphism. But in your simple case with only one switch(x) block, I will not recommend to do that. If your real code is more complex, then consider to extract classes which will hold set of functionality (Do1, Do2, Do3) and will decide upon that functionality execution. E.g. calling code:
IDo ido = CreateIDo(x);
ido.Do(y);
Yes, that's all. Extremely clean. Here is IDo interface creation code:
public static IDo CreateIDo(string x)
{
switch (x)
{
case "A": return new A();
case "B": return new B();
default:
return new C();
}
}
And here is class A, that encapsulates first set of methods and decisions upon executing them:
public interface IDo
{
void Do(string y);
}
public class A : IDo
{
public void Do(string y)
{
switch (y)
{
case "1": Do1(); break;
case "2": Do2(); break;
case "3": Do3(); break;
}
}
private void Do1() { }
private void Do2() { }
private void Do3() { }
}
Again, use this in case your real code is more complex.
I would use an IEnumerable collection of Tuples and an Action delegate to define your list of methods to be called, create the list as a private field or in the class initialiser, or to be flexible you can add Tuples to a public property as needed. If you need to pass in parameters use one of the overloaded versions of the Action delegate ie: Action(t1, t2) etc.
If you need a return value use the Func delegate as per the other answer.
IEnumerable<Tuple<string, string, Action>> actions = new List<Tuple<string, string, Action>>() {
Tuple.Create<string, string, Action>("A", "1", SomeMethod1),
Tuple.Create<string, string, Action>("A", "2", SomeMethod2)
};
string x = "A";
string y = "2";
var action = actions.FirstOrDefault(t => ((t.Item1 == x) && (t.Item2 == y)));
if (action != null)
action.Item3();
else
DoSomeDefaultMethod();
public void SomeMethod1() { // Whatever you want to do }
public void SomeMethod2() { // Whatever you want to do }
public void DoSomeDefaultMethod() { // Default Method }
void Main()
{
Dictionary<string, Action> d = new Dictionary<string, Action>()
{
{"A1", Do1},
{"A2", Do2},
{"A3", Do3},
{"B1", Do4},
{"B2", Do5},
{"B3", Do6},
{"1", Do7},
{"2", Do8},
{"3", Do9}
};
var x = "A";
var y = "1";
var action = x == "A" || x == "B" ? x + y : y;
if (d.ContainsKey(action))
d[action]();
}
public void Do1() {}
public void Do2() {}
public void Do3() {}
public void Do4() {}
public void Do5() {}
public void Do6() {}
public void Do7() {}
public void Do8() {}
public void Do9() {}
EDIT
I remembered about this fluent functional switch:
var sw = new Switch<string>(action)
.Case("A1", s => Do1())
.Case("A2", s => Do2());
Consider this if you don't want to change much of your current structure,(and don't want to create new types etc.)
Add them to tuples like below
var tuples = new List<Tuple<string,string,Func<>>()>(); // Func should be of your Do() type
Add your conditional data with the related funcs to the list
tuples.Add(new Tuple<string,string,Func<>>("A","1", Do1()));
...
Just call it when required using your conditionals directly
var function = tuples.Where(x => x.item1 == "A" && x.item2 == "1").Select(x => x.item3);
function.Invoke(); // to call it.
Now if you got more conditionals in future, you can just add them to the list without changing any code.
Use some thing like this . only three if would do.
if (x == "A")
{
int a = (y == "1") ? do1() : ((y == "2") ? do2() : do3());
}
}
int do1() { return 10; }
int do2() { return 10; }
int do3() { return 10; }
I guess the same kind of switch on X is performed in more than one place in your code, if so kindly refactor it and use polymorphism instead
If X is string first replace the typecode with class and use polymorphism.

Categories