How to get all the values within multiple curly braces - c#

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;
}

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];

C# Switch-case string end with

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";
}

Replace 4 different characters

I'm trying to take the user input, E.G. ATCG and replace the letters with TAGC. These are DNA Complementary Bases. For example, if the user was to enter ATCGGGC it would output TAGCCCG. I've managed to replace 1 character, but I'm not sure how to get the others to replace.
namespace DNA_Replication_EASY
{
class Program
{
static string input1;
public static string InputBaseWithSpaces()
{
return string.Join(" ", input1.ToCharArray());
}
public static string OpposingBases()
{
string outputBases1 = input1.Replace("A", "T");
return outputBases1;
}
static void Main(string[] args)
{
Console.WriteLine("Please type out your DNA strand bases E.g. A T C G C A T G");
input1 = Console.ReadLine();
Console.WriteLine(InputBaseWithSpaces());
Console.WriteLine(OpposingBases());
Console.ReadLine();
}
}
}
Use Regex.Replace to replace string based on a dictionary (map):
Dictionary<string, string> complementary = new Dictionary<string,string>()
{
{ "A", "T" },
{ "T", "A" },
{ "C", "G" },
{ "G", "C" }
};
string input = "ATCG";
string result = Regex.Replace(input, "[ATCG]", match => complementary[match.Value]);
this replaces any of the "ATCG" character match with corresponding value from dictionary.
string MakeOpposite(string sourceString) {
var opposites = new Dictionary<char, char> {
{ 'A', 'T' },
{ 'T', 'A' },
{ 'G', 'C' },
{ 'C', 'G' }
};
var oppositeString = new string(sourceString.Select(x => opposites[x]));
return oppositeString;
}
Convert it to a char array and replace in place
string input = "ATCG";
//TAGC
char[] inputChar = input.ToCharArray();
for(int i=0;i< inputChar.Length; i++)
{
switch(inputChar[i])
{
case 'A':
inputChar[i]='T';
break;
case 'T':
inputChar[i]='A';
break;
case 'G':
inputChar[i]='C';
break;
case 'C':
inputChar[i]='G';
break;
}
}
var output =new string(inputChar);
I would use a foreach and switch statement over your Char Array to replace each letter.
foreach (char base in strand)
{
switch (base.ToString())
{
case "g":
//replace code
break;
case "c":
//replace code
break;
}
}
You should instead write a routine to go through character by character and do the replacement (don't use the string.replace method).
private string ConvertDNA(string original)
{
StringBuilder newone = new StringBuilder();
foreach(char c in original)
{
switch(c)
{
case 'A':
newone.Append('T');
break;
case 'T':
newone.Append('A');
break;
case 'C':
newone.Append('G');
break;
case 'G':
newone.Append('C');
break;
default:
newone.Append(c);
break;
}
}
return newone.ToString();
}
Note that if your original string is certain forms of Unicode, this could do funny things. You should use stringbuilder rather than the += syntax in the other answers because its more efficient.
One way to do it is by using a Switch statement
public static string OpposingBases()
{
string outputBases1;
foreach(var s in input1)
{
switch (s)
{
case "A":
outputBases1 +="T";
break;
case "T":
outputBases1 +="A";
break;
case "C":
outputBases1 +="G";
break;
case "G":
outputBases1 +="C";
break;
case " ":
outputBases1 +=" ";
break;
default:
break;
}
}
return outputBases1;
}
Simple solution, but you can do better:
code = code.Replace("A","x").Replace("C","y").Replace("T","A").Replace("G","C").Replace("x","T").Replace("y","G");
You could do this
public static string OpposingBases()
{
var baseDictionary = new Dictionary<char, char>()
{
{'A', 'T'},
{'T', 'A'},
{'C', 'G'},
{'G', 'C'}
};
return input1.Where(baseDictionary.ContainsKey).Aggregate("", (current, c) => current + baseDictionary[c]);
}

I want something like the switch statement (but different of course)

Is there a C# construct like the switch statement that allows control to fall through the next level? I have something like this:
public static IEnumerable<string> SeverityOrHigher(string severity)
{
var result = new List<string>();
switch (severity.ToUpper())
{
case "ALL":
result.Add("ALL");
case "DEBUG":
result.Add("DEBUG");
case "INFO":
result.Add("INFO");
case "WARN":
result.Add("WARN");
case "ERROR":
result.Add("ERROR");
case "FATAL":
result.Add("FATAL");
case "OFF":
result.Add("OFF");
default:
break;
}
return result;
}
...which clearly does not work in C#, (Control cannot fall through from one case label...) yet it seems to me like it should. I know it expects breaks in there, but that would not give me the data flow I'm looking for. What can be done to make this happen the way I'd like?
In your case you can emulate "falling case" with a little bit of LINQ:
public static IEnumerable<string> SeverityOrHigher(string severity)
{
var result = new List<string>()
{ "ALL", "DEBUG", "INFO", "WARN", "ERROR", "FATAL", "OFF" };
return result.SkipWhile(l => l != severity.ToUpper()).ToArray();
}
Along with gotos, etc, you could do with this an enum and a bit of linq:
public static IEnumerable<Severity> SeverityOrHigher(Severity severity)
{
var value = (int) severity;
return Enum.GetValues(typeof (Severity))
.Cast<int>()
.Where(i => i >= value)
.Select(i => (Severity) i);
}
public enum Severity
{
All = 0,
Trace = 1,
Debug = 2,
Information = 3,
Warning = 4,
Error = 5,
Fatal = 6
}
It is not the optimal solution but you could use the goto statement like this:
switch (severity.ToUpper())
{
case "ALL":
result.Add("ALL");
goto case "DEBUG";
case "DEBUG":
result.Add("DEBUG");
goto case "INFO";
case "INFO":
result.Add("INFO");
goto case "WARN";
case "WARN":
result.Add("WARN");
goto case "ERROR";
case "ERROR":
result.Add("ERROR");
goto case "FATAL";
case "FATAL":
result.Add("FATAL");
goto case "OFF";
case "OFF":
result.Add("OFF");
break;
default:
break;
}
Use goto:
switch (severity.ToUpper())
{
case "ALL":
result.Add("ALL");
goto case "DEBUG";
case "DEBUG":
result.Add("DEBUG");
goto case "INFO";
case "INFO":
result.Add("INFO");
goto case "WARN";
case "WARN":
result.Add("WARN");
goto case "ERROR";
case "ERROR":
result.Add("ERROR");
goto case "FATAL";
case "FATAL":
result.Add("FATAL");
goto case "OFF";
case "OFF":
result.Add("OFF");
break;
default:
break;
}
Microsoft (implicitly) recommends this use: http://msdn.microsoft.com/en-us/library/06tc147t(v=vs.71).aspx
#nemesv's Linq answer is way better solution but if you want to do it with switch you could do like this and will get same result.
public static IEnumerable<string> SeverityOrHigher(string severity)
{
var lastFound = -1;
var severityList = new List<string>() { "ALL", "DEBUG", "INFO", "WARN", "ERROR", "FATAL", "OFF" };
var results = new List<string>();
foreach (var t in severityList)
{
if (lastFound > -1)
{
for (var index = lastFound + 1; index < severityList.Count; index++)
{
results.Add(severityList[index]);
}
return results;
}
switch (severity.ToUpper())
{
case "ALL":
results.Add(severity);
lastFound = 0;
break;
case "DEBUG":
lastFound = 1;
results.Add(severity);
break;
case "INFO":
lastFound = 2;
results.Add(severity);
break;
case "WARN":
lastFound = 3;
results.Add(severity);
break;
case "ERROR":
lastFound = 4;
results.Add(severity);
break;
case "FATAL":
lastFound = 5;
results.Add(severity);
break;
case "OFF":
lastFound = 6;
results.Add(severity);
break;
}
}
return results;
}
Test:
var list = SeverityOrHigher("ALL");
foreach (var severity in list)
{
Console.WriteLine(severity);
}
Console.ReadKey();
Does not look very nice, but could do the job for you:
string s = severity.ToUpper();
result.add("OFF");
if (s == "OFF")
return result;
result.add("FATAL");
if (s == "FATAL")
return result;
result.add("ERROR");
if (s == "ERROR")
return result;
// ...
result.add("ALL");
return result;
I'd go with somehting like creating another list which represents all valid severities and checking if the input severity is one of them:
public static IEnumerable<string> SeverityOrHigher(string severity)
{
var result = new List<string>();
var severities = new List<string> { "ALL", "DEBUG", "INFO", "WARN", "ERROR", "FATAL", "OFF" };
severity = severity.ToUpper();
if (severities.Contain(severity))
result.Add(severity);
return result;
}

Extension method to convert SubSonic SqlQuery object to plain SQL

I sometimes need to see what SQL statement SubSonic generates.
That works great with:
SqlQuery qry = DB.Select().From<Product>()
.Where(Products.Columns.Name).IsEqualTo("Productname");
Console.WriteLine(qry.BuildSqlStatement());
However that returns the query with parameters (SELECT ... WHERE productname = ?productname). So, I always have to find the real values in my code and replace the parameters with the propper formatted value (e.g. productname = 'Productname') which can be really annoying with complex querys.
So, I decided to make an extension method that I want to share (look at my answer for the code).
It is far away from being perfect, but it fits my needs for now.
But I can use
Console.WriteLine(qry.BuildSqlStatementDebug());
then copy the result to Clipboard and run it agains my DB from Query Browser.
using System;
using SubSonic;
namespace MyNamespace.ExtensionMethods
{
public static class SubsonicSqlQueryExtensionMethods
{
public static String BuildSqlStatementDebug(this SqlQuery qry)
{
var result = qry.BuildSqlStatement();
foreach (var c in qry.Constraints)
{
if (c.Comparison == Comparison.BetweenAnd)
{
result = result.Replace(c.ParameterName + "_start", GetFormattedValue(c.StartValue, c.DbType));
result = result.Replace(c.ParameterName + "_end", GetFormattedValue(c.EndValue, c.DbType));
}
else
{
result = result.Replace(c.ParameterName, GetFormattedValue(c.ParameterValue, c.DbType));
}
}
return result;
}
// Works for MySQL
private static readonly String formatter_date = "'{0:yyyy-MM-dd}'";
private static readonly String formatter_datetime = "'{0:yyyy-MM-dd hh:mm:ss}'";
private static readonly String formatter_string = "'{0}'";
private static String GetFormattedValue(Object value, System.Data.DbType type)
{
switch (type)
{
case System.Data.DbType.AnsiString:
return String.Format(formatter_string, value);
case System.Data.DbType.AnsiStringFixedLength:
return String.Format(formatter_string, value);
//case System.Data.DbType.Binary:
// break;
case System.Data.DbType.Boolean:
return (Boolean)value == true ? "true" : "false";
//case System.Data.DbType.Byte:
// break;
//case System.Data.DbType.Currency:
// break;
case System.Data.DbType.Date:
return String.Format(formatter_date, value); break;
case System.Data.DbType.DateTime:
return String.Format(formatter_datetime, value); break;
case System.Data.DbType.DateTime2:
return String.Format(formatter_datetime, value); break;
//case System.Data.DbType.DateTimeOffset:
// break;
//case System.Data.DbType.Decimal:
// break;
//case System.Data.DbType.Double:
// break;
case System.Data.DbType.Guid:
return String.Format(formatter_string, value);
//case System.Data.DbType.Int16:
// break;
//case System.Data.DbType.Int32:
// break;
//case System.Data.DbType.Int64:
// break;
//case System.Data.DbType.Object:
// break;
//case System.Data.DbType.SByte:
// break;
//case System.Data.DbType.Single:
// break;
case System.Data.DbType.String:
return String.Format(formatter_string, value);
case System.Data.DbType.StringFixedLength:
return String.Format(formatter_string, value);
//case System.Data.DbType.Time:
// break;
//case System.Data.DbType.UInt16:
// break;
//case System.Data.DbType.UInt32:
// break;
//case System.Data.DbType.UInt64:
// break;
//case System.Data.DbType.VarNumeric:
// break;
case System.Data.DbType.Xml:
return String.Format(formatter_string, value);
default:
return value.ToString();
}
}
}
}

Categories