Easy ways to increment with number and letters after checking DB - c#

Using C# and ASP.NET
Lnna is based on values that the user inputs.
I can get those values.
Lnnai is the full form.
Last value 'i' should be incremented through 0-9,a-z and then A-Z. What would be the easiest way to look in DB for values and increment?
var Lnna = L + nn + a;
var ichars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".ToCharArray();
var i = ?

Examining an ASCII table yeilds
0-9 48-57
A-Z 65-90
a-z 97-122
It is much easier to increment a number than a letter so I converted the last letter to its ASCII value and incremented that then cast it back to a char and then toString.
private void Form2_Load(object sender, EventArgs e)
{
string input = "Lnnnai";
bool foundInDatabase = false;
//set your value after db query
if (foundInDatabase)
{ }//your code here
else
{
string s = input.Substring(input.Length - 1, 1);
s = IncrementCharacter(s);
Debug.Print(s);
string newString = input.Remove(input.Length - 1, 1);
newString += s;
Debug.Print(newString);
}
}
private string IncrementCharacter(String character)
{
int code = Char.ConvertToUtf32(character,0);
switch (code)
{
case 57:
return "A";
case 90:
return "a";
default:
code += 1;
return ((char)code).ToString();
}
}
to use Debug.Print import System.Diagnostics

This is the method I used. It works perfectly.
int tl = items.ShelfId;
var ttl = await _context.Shelfs.FirstOrDefaultAsync(b => b.ShelfId == tl);
var l = ttl.Name;
int tnn = items.CategoryId;
var ttnn = await _context.Categories.FirstOrDefaultAsync(b => b.CategoryId == tnn);
var nn = ttnn.Subject;
string a = items.AuthorLastName.Substring(0, 1);
var lnna = l + nn + a;
var ichars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".ToCharArray();
var currenti = _context.Items.Count(i => i.LibraryItemNumber.Contains(lnna));
if (currenti > 0 && currenti < 62)
{
var i = ichars[currenti];
var LNNAI = lnna + i;
items.LibraryItemNumber = LNNAI;
}
else if (currenti == 0)
{
var i = ichars[0];
var LNNAI = lnna + i;
items.LibraryItemNumber = LNNAI;
}
else
{
items.LibraryItemNumber = "Exceed";
}

Related

Find count of each consecutive characters

Need to find the count of each consecutive characters in a row.
Ex: aaaabbccaa
output: 4a2b2c2a
Character may repeat but need to count only consecutive ones. I also need to maintain original sequence.
I tried following but it groups all characters so was not useful.
str.GroupBy(c => c).Select(g => new { g.Key, Count = g.Count() }).ToList().ForEach(x => str+= x.Count + "" + x.Key)
Regular expression to the rescue ?
var myString = "aaaabbccaa";
var pattern = #"(\w)\1*";
var regExp = new Regex(pattern);
var matches = regExp.Matches(myString);
var tab = matches.Select(x => String.Format("{0}{1}", x.Value.First(), x.Value.Length));
var result = String.Join("", tab);
Here is a LINQ solution:
var input = "aaaabbccaa";
var result = string.IsNullOrEmpty(input) ? "" : string.Join("",input.Skip(1)
.Aggregate((t:input[0].ToString(),o:Enumerable.Empty<string>()),
(a,c)=>a.t[0]==c ? (a.t+c,a.o) : (c.ToString(),a.o.Append(a.t)),
a=>a.o.Append(a.t).Select(p => $"{p.Length}{p[0]}")));
Here is the iterator solution:
var result = RleString("aaaabbccaa");
private static IEnumerable<(char chr, int count)> Rle(string s)
{
if (string.IsNullOrEmpty(s)) yield break;
var lastchar = s.First(); // or s[0]
var count = 1;
foreach (char letter in s.Skip(1))
{
if (letter != lastchar)
{
yield return (lastchar, count);
lastchar = letter;
count = 0;
}
count++;
}
if (count > 0)
yield return (lastchar, count);
}
private static string RleString(string s)
{
return String.Join("",Rle(s).Select(z=>$"{z.count}{z.chr}"));
}
Non-LINQ solution (dotnetfiddle):
using System;
using System.Text;
public class Program
{
public static void Main()
{
// produces 4a2b2c2a
Console.WriteLine(GetConsecutiveGroups("aaaabbccaa"));
}
private static string GetConsecutiveGroups(string input)
{
var result = new StringBuilder();
var sb = new StringBuilder();
foreach (var c in input)
{
if (sb.Length == 0 || sb[sb.Length - 1] == c)
{
sb.Append(c);
}
else
{
result.Append($"{sb.Length}{sb[0]}");
sb.Clear();
sb.Append(c);
}
}
if (sb.Length > 0)
{
result.Append($"{sb.Length}{sb[0]}");
}
return result.ToString();
}
}
This small program will do the trick, but it's not a single line nice linq statement. Just my two cents.
using System;
using System.Linq;
using System.Collections.Generic;
public class Simple {
public static void Main() {
var text = "aaaabbccaa"; //output: 4a3b2c2a
var lista = new List<string>();
var previousLetter = text.Substring(1,1);
var item = string.Empty;
foreach (char letter in text)
{
if (previousLetter == letter.ToString()){
item += letter.ToString();
}
else
{
lista.Add(item);
item = letter.ToString();
}
previousLetter = letter.ToString();
}
lista.Add(item);
foreach (var i in lista)
Console.WriteLine(i.Substring(1,1) + i.Select(y => y).ToList().Count().ToString());
}
}
Here is my non-LINQ version that is quite fast compared to LINQ or Regex:
var prevChar = str[0];
var ct = 1;
var s = new StringBuilder();
var len = str.Length;
for (int j2 = 1; j2 < len; ++j2) {
if (str[j2] == prevChar)
++ct;
else {
s.Append(ct);
s.Append(prevChar);
ct = 1;
prevChar = str[j2];
}
}
s.Append(ct);
s.Append(prevChar);
var final = s.ToString();
}
My LINQ version looks like this, but uses a couple of extension methods I already had:
var ans = str.GroupByRuns().Select(s => $"{s.Count()}{s.Key}").Join();
var chars = "aaaabbccaa".ToCharArray();
int counter = 1;
for (var i = 0; i < chars.Count(); i++)
{
if (i + 1 >= chars.Count() || chars[i] != chars[i + 1])
{
Console.Write($"{counter}{chars[i]}");
counter = 1;
}
else
{
counter++;
}
}
You could have a character var and a counter var outside your Linq scope to keep track of the previous character and the current count and then use linq foreach, but I am just as curious as the rest to why you insist on doing this. Even if you do, the Solution may not be as easy to read as an iterative version and readability and maintenance overhead is very import if anyone else is ever going to read it.

Get text between specific character

I want to get the text between ';' character. However if there are 3 matches like that, i want to get the text between ';' character where current cursor position. I am using multine textbox.
Example;
select * from database;
----> **Lets say my cursor is here**
select
orders from
customer;
select * from employees;
So, i only want to get 'select orders from customer' text.
Could you please share your thoughts on it?
To achieve this, you first have to find all indicies of ;. To do this, iterate through all indicies (source):
private List<int> AllIndicesOf(string strToSearch, string fullText)
{
List<int> foundIndices = new List<int>();
for (int i = fullText.IndexOf(strToSearch); i > -1; i = fullText.IndexOf(strToSearch, i + 1))
{
foundIndices.Add(i + 1);
}
return foundIndices;
}
Then you have to compare your position to those indices, since you only want the index (of ;) that follows immediately after your cursor:
List<int> indicies = AllIndicesOf(";", txtBxText.Text);
try
{
if (indicies.Count > 0)
{
int cursorPos = txtBxText.SelectionStart;
var indicesBefore = indicies.Where(x => x < cursorPos);
int beginIndex = indicesBefore.Count() > 0 ? indicesBefore.Last() : 0;
int endIndex = indicies.Where(x => x > beginIndex).First();
txtBxSelected.Text = txtBxText.Text.Substring(beginIndex, endIndex - beginIndex);
}
}
catch { }
The try-catch statement is used to prevent an Exception if your cursors position is after all other indices.
A sample project can be downloaded here.
This solution perfectly works although you need to check it again and consider some possible exceptions. I did not consider them myself because I thought it was better to be handled by you. I also used richTextBox which is better than the multi line text box. Enjoy the code bro
private void button1_Click(object sender, EventArgs e)
{
var ultimateResult = string.Empty;
var cusrPosition = richTextBox1.SelectionStart;
var currentStr = string.Empty;
var strDic = new Dictionary<string,int>();
var textArr = richTextBox1.Text.ToCharArray();
for (var i = 0; i < textArr.Count(); i++)
{
if (textArr[i] != ';')
currentStr = currentStr + textArr[i];
else
{
strDic.Add(currentStr,i);
currentStr = string.Empty;
}
}
ultimateResult = strDic.First(item => item.Value >= cusrPosition).Key;
textBox1.Text = ultimateResult;
}

Make every other a-z letter Upper / Lower case, ignoring whitespace

Can somebody tell me what I am doing wrong please? can't seem to get the expected output, i.e. ignore whitespace and only upper/lowercase a-z characters regardless of the number of whitespace characters
my code:
var sentence = "dancing sentence";
var charSentence = sentence.ToCharArray();
var rs = "";
for (var i = 0; i < charSentence.Length; i++)
{
if (charSentence[i] != ' ')
{
if (i % 2 == 0 && charSentence[i] != ' ')
{
rs += charSentence[i].ToString().ToUpper();
}
else if (i % 2 == 1 && charSentence[i] != ' ')
{
rs += sentence[i].ToString().ToLower();
}
}
else
{
rs += " ";
}
}
Console.WriteLine(rs);
Expected output: DaNcInG sEnTeNcE
Actual output: DaNcInG SeNtEnCe
I use flag instead of i because (as you mentioned) white space made this algorithm work wrong:
var sentence = "dancing sentence";
var charSentence = sentence.ToCharArray();
var rs = "";
var flag = true;
for (var i = 0; i < charSentence.Length; i++)
{
if (charSentence[i] != ' ')
{
if (flag)
{
rs += charSentence[i].ToString().ToUpper();
}
else
{
rs += sentence[i].ToString().ToLower();
}
flag = !flag;
}
else
{
rs += " ";
}
}
Console.WriteLine(rs);
Try a simple Finite State Automata with just two states (upper == true/false); another suggestion is to use StringBuilder:
private static string ToDancing(string value) {
if (string.IsNullOrEmpty(value))
return value;
bool upper = false;
StringBuilder sb = new StringBuilder(value.Length);
foreach (var c in value)
if (char.IsLetter(c))
sb.Append((upper = !upper) ? char.ToUpper(c) : char.ToLower(c));
else
sb.Append(c);
return sb.ToString();
}
Test
var sentence = "dancing sentence";
Console.Write(ToDancing(sentence));
Outcome
DaNcInG sEnTeNcE
I think you should declare one more variable called isUpper. Now you have two variables, i indicates the index of the character that you are iterating next and isUpper indicates whether a letter should be uppercase.
You increment i as usual, but set isUpper to true at first:
// before the loop
boolean isUpper = true;
Then, rather than checking whether i is divisible by 2, check isUpper:
if (isUpper)
{
rs += charSentence[i].ToString().ToUpper();
}
else
{
rs += sentence[i].ToString().ToLower();
}
Immediately after the above if statement, "flip" isUpper:
isUpper = !isUpper;
Linq version
var sentence = "dancing sentence";
int i = 0;
string result = string.Concat(sentence.Select(x => { i += x == ' ' ? 0 : 1; return i % 2 != 0 ? char.ToUpper(x) : char.ToLower(x); }));
Sidenote:
please replace charSentence[i].ToString().ToUpper() with char.ToUpper(charSentence[i])
Thanks #Dmitry Bychenko. Best Approach. But i thought as per the OP's (might be a fresher...) mindset, what could be the solution. Here i have the code as another solution.
Lengthy code. I myself don't like but still representing
class Program
{
static void Main(string[] args)
{
var sentence = "dancing sentence large also";
string newString = string.Empty;
StringBuilder newStringdata = new StringBuilder();
string[] arr = sentence.Split(' ');
for (int i=0; i< arr.Length;i++)
{
if (i==0)
{
newString = ReturnEvenModifiedString(arr[i]);
newStringdata.Append(newString);
}
else
{
if(char.IsUpper(newString[newString.Length - 1]))
{
newString = ReturnOddModifiedString(arr[i]);
newStringdata.Append(" ");
newStringdata.Append(newString);
}
else
{
newString = ReturnEvenModifiedString(arr[i]);
newStringdata.Append(" ");
newStringdata.Append(newString);
}
}
}
Console.WriteLine(newStringdata.ToString());
Console.Read();
}
//For Even Test
private static string ReturnEvenModifiedString(string initialString)
{
string newString = string.Empty;
var temparr = initialString.ToCharArray();
for (var i = 0; i < temparr.Length; i++)
{
if (temparr[i] != ' ')
{
if (i % 2 == 0 && temparr[i] != ' ')
{
newString += temparr[i].ToString().ToUpper();
}
else
{
newString += temparr[i].ToString().ToLower();
}
}
}
return newString;
}
//For Odd Test
private static string ReturnOddModifiedString(string initialString)
{
string newString = string.Empty;
var temparr = initialString.ToCharArray();
for (var i = 0; i < temparr.Length; i++)
{
if (temparr[i] != ' ')
{
if (i % 2 != 0 && temparr[i] != ' ')
{
newString += temparr[i].ToString().ToUpper();
}
else
{
newString += temparr[i].ToString().ToLower();
}
}
}
return newString;
}
}
OUTPUT

How to replace each 3rd or 4th character in a string with a newline? C#

For instance I've got this string: "Is it allowed to enter this room without asking?"
I'd like to place each 3rd or 4th ' ' a newline to get it to be like: "Is it allowed to(newline)enter this room without(newline)without asking?"
Here's a very verbose solution, based on the assumption that each word is separated by others only with a space.
var splitted = "Is it allowed to enter this room without asking?".Split(' ');
StringBuilder str = new StringBuilder();
int i = 1;
foreach (var word in splitted)
{
str.Append(word);
if (i % 3 == 0)
{
str.Append(System.Environment.NewLine);
}
else
{
str.Append(" ");
}
i++;
}
var result = str.ToString();
static void Main(string[] args)
{
const string text = "Is it allowed to enter this room without asking?";
string newText = null;
int count = 0;
foreach (char c in text)
{
string temp = c.ToString();
if (c == ' ')
{
count ++;
bool placeNewLine = false;
Random random = new Random();
if (random.Next(0, 2) == 1) placeNewLine = true;
if (count == 4 || (placeNewLine && count ==3))
{
temp = Environment.NewLine;
count = 0;
}
}
newText += temp;
}
Console.WriteLine(newText);
Console.ReadLine();
}

Splitting CSV files with commas in the values [duplicate]

How to split the CSV file in c sharp? And how to display this?
I've been using the TextFieldParser Class in the Microsoft.VisualBasic.FileIO namespace for a C# project I'm working on. It will handle complications such as embedded commas or fields that are enclosed in quotes etc. It returns a string[] and, in addition to CSV files, can also be used for parsing just about any type of structured text file.
Display where? About splitting, the best way is to use a good library to that effect.
This library is pretty good, I can recommend it heartily.
The problems using naïve methods is that the usually fail, there are tons of considerations without even thinking about performance:
What if the text contains commas
Support for the many existing formats (separated by semicolon, or text surrounded by quotes, or single quotes, etc.)
and many others
Import Micorosoft.VisualBasic as a reference (I know, its not that bad) and use Microsoft.VisualBasic.FileIO.TextFieldParser - this handles CSV files very well, and can be used in any .Net language.
read the file one line at a time, then ...
foreach (String line in line.Split(new char[] { ',' }))
Console.WriteLine(line);
This is a CSV parser I use on occasion.
Usage: (dgvMyView is a datagrid type.)
CSVReader reader = new CSVReader("C:\MyFile.txt");
reader.DisplayResults(dgvMyView);
Class:
using System.IO;
using System.Text.RegularExpressions;
using System.Windows.Forms;
public class CSVReader
{
private const string ESCAPE_SPLIT_REGEX = "({1}[^{1}]*{1})*(?<Separator>{0})({1}[^{1}]*{1})*";
private string[] FieldNames;
private List<string[]> Records;
private int ReadIndex;
public CSVReader(string File)
{
Records = new List<string[]>();
string[] Record = null;
StreamReader Reader = new StreamReader(File);
int Index = 0;
bool BlankRecord = true;
FieldNames = GetEscapedSVs(Reader.ReadLine());
while (!Reader.EndOfStream)
{
Record = GetEscapedSVs(Reader.ReadLine());
BlankRecord = true;
for (Index = 0; Index <= Record.Length - 1; Index++)
{
if (!string.IsNullOrEmpty(Record[Index])) BlankRecord = false;
}
if (!BlankRecord) Records.Add(Record);
}
ReadIndex = -1;
Reader.Close();
}
private string[] GetEscapedSVs(string Data)
{
return GetEscapedSVs(Data, ",", "\"");
}
private string[] GetEscapedSVs(string Data, string Separator, string Escape)
{
string[] Result = null;
int Index = 0;
int PriorMatchIndex = 0;
MatchCollection Matches = Regex.Matches(Data, string.Format(ESCAPE_SPLIT_REGEX, Separator, Escape));
Result = new string[Matches.Count];
for (Index = 0; Index <= Result.Length - 2; Index++)
{
Result[Index] = Data.Substring(PriorMatchIndex, Matches[Index].Groups["Separator"].Index - PriorMatchIndex);
PriorMatchIndex = Matches[Index].Groups["Separator"].Index + Separator.Length;
}
Result[Result.Length - 1] = Data.Substring(PriorMatchIndex);
for (Index = 0; Index <= Result.Length - 1; Index++)
{
if (Regex.IsMatch(Result[Index], string.Format("^{0}[^{0}].*[^{0}]{0}$", Escape))) Result[Index] = Result[Index].Substring(1, Result[Index].Length - 2);
Result[Index] = Result[Index].Replace(Escape + Escape, Escape);
if (Result[Index] == null) Result[Index] = "";
}
return Result;
}
public int FieldCount
{
get { return FieldNames.Length; }
}
public string GetString(int Index)
{
return Records[ReadIndex][Index];
}
public string GetName(int Index)
{
return FieldNames[Index];
}
public bool Read()
{
ReadIndex = ReadIndex + 1;
return ReadIndex < Records.Count;
}
public void DisplayResults(DataGridView DataView)
{
DataGridViewColumn col = default(DataGridViewColumn);
DataGridViewRow row = default(DataGridViewRow);
DataGridViewCell cell = default(DataGridViewCell);
DataGridViewColumnHeaderCell header = default(DataGridViewColumnHeaderCell);
int Index = 0;
ReadIndex = -1;
DataView.Rows.Clear();
DataView.Columns.Clear();
for (Index = 0; Index <= FieldCount - 1; Index++)
{
col = new DataGridViewColumn();
col.CellTemplate = new DataGridViewTextBoxCell();
header = new DataGridViewColumnHeaderCell();
header.Value = GetName(Index);
col.HeaderCell = header;
DataView.Columns.Add(col);
}
while (Read())
{
row = new DataGridViewRow();
for (Index = 0; Index <= FieldCount - 1; Index++)
{
cell = new DataGridViewTextBoxCell();
cell.Value = GetString(Index).ToString();
row.Cells.Add(cell);
}
DataView.Rows.Add(row);
}
}
}
I had got the result for my query. its like simple like i had read a file using io.file. and all the text are stored into a string. After that i splitted with a seperator. The code is shown below.
using System;
using System.Collections.Generic;
using System.Text;
namespace CSV
{
class Program
{
static void Main(string[] args)
{
string csv = "user1, user2, user3,user4,user5";
string[] split = csv.Split(new char[] {',',' '});
foreach(string s in split)
{
if (s.Trim() != "")
Console.WriteLine(s);
}
Console.ReadLine();
}
}
}
The following function takes a line from a CSV file and splits it into a List<string>.
Arguments:
string line = the line to split
string textQualifier = what (if any) text qualifier (i.e. "" or "\"" or "'")
char delim = the field delimiter (i.e. ',' or ';' or '|' or '\t')
int colCount = the expected number of fields (0 means don't check)
Example usage:
List<string> fields = SplitLine(line, "\"", ',', 5);
// or
List<string> fields = SplitLine(line, "'", '|', 10);
// or
List<string> fields = SplitLine(line, "", '\t', 0);
Function:
private List<string> SplitLine(string line, string textQualifier, char delim, int colCount)
{
List<string> fields = new List<string>();
string origLine = line;
char textQual = '"';
bool hasTextQual = false;
if (!String.IsNullOrEmpty(textQualifier))
{
hasTextQual = true;
textQual = textQualifier[0];
}
if (hasTextQual)
{
while (!String.IsNullOrEmpty(line))
{
if (line[0] == textQual) // field is text qualified so look for next unqualified delimiter
{
int fieldLen = 1;
while (true)
{
if (line.Length == 2) // must be final field (zero length)
{
fieldLen = 2;
break;
}
else if (fieldLen + 1 >= line.Length) // must be final field
{
fieldLen += 1;
break;
}
else if (line[fieldLen] == textQual && line[fieldLen + 1] == textQual) // escaped text qualifier
{
fieldLen += 2;
}
else if (line[fieldLen] == textQual && line[fieldLen + 1] == delim) // must be end of field
{
fieldLen += 1;
break;
}
else // not a delimiter
{
fieldLen += 1;
}
}
string escapedQual = textQual.ToString() + textQual.ToString();
fields.Add(line.Substring(1, fieldLen - 2).Replace(escapedQual, textQual.ToString())); // replace escaped qualifiers
if (line.Length >= fieldLen + 1)
{
line = line.Substring(fieldLen + 1);
if (line == "") // blank final field
{
fields.Add("");
}
}
else
{
line = "";
}
}
else // field is not text qualified
{
int fieldLen = line.IndexOf(delim);
if (fieldLen != -1) // check next delimiter position
{
fields.Add(line.Substring(0, fieldLen));
line = line.Substring(fieldLen + 1);
if (line == "") // final field must be blank
{
fields.Add("");
}
}
else // must be last field
{
fields.Add(line);
line = "";
}
}
}
}
else // if there is no text qualifier, then use existing split function
{
fields.AddRange(line.Split(delim));
}
if (colCount > 0 && colCount != fields.Count) // count doesn't match expected so throw exception
{
throw new Exception("Field count was:" + fields.Count.ToString() + ", expected:" + colCount.ToString() + ". Line:" + origLine);
}
return fields;
}
Problem: Convert a comma separated string into an array where commas in "quoted strings,,," should not be considered as separators but as part of an entry
Input:
String: First,"Second","Even,With,Commas",,Normal,"Sentence,with ""different"" problems",3,4,5
Output:
String-Array: ['First','Second','Even,With,Commas','','Normal','Sentence,with "different" problems','3','4','5']
Code:
string sLine;
sLine = "First,\"Second\",\"Even,With,Commas\",,Normal,\"Sentence,with \"\"different\"\" problems\",3,4,5";
// 1. Split line by separator; do not split if separator is within quotes
string Separator = ",";
string Escape = '"'.ToString();
MatchCollection Matches = Regex.Matches(sLine,
string.Format("({1}[^{1}]*{1})*(?<Separator>{0})({1}[^{1}]*{1})*", Separator, Escape));
string[] asColumns = new string[Matches.Count + 1];
int PriorMatchIndex = 0;
for (int Index = 0; Index <= asColumns.Length - 2; Index++)
{
asColumns[Index] = sLine.Substring(PriorMatchIndex, Matches[Index].Groups["Separator"].Index - PriorMatchIndex);
PriorMatchIndex = Matches[Index].Groups["Separator"].Index + Separator.Length;
}
asColumns[asColumns.Length - 1] = sLine.Substring(PriorMatchIndex);
// 2. Remove quotes
for (int Index = 0; Index <= asColumns.Length - 1; Index++)
{
if (Regex.IsMatch(asColumns[Index], string.Format("^{0}[^{0}].*[^{0}]{0}$", Escape))) // If "Text" is sourrounded by quotes (but ignore double quotes => "Leave ""inside"" quotes")
{
asColumns[Index] = asColumns[Index].Substring(1, asColumns[Index].Length - 2); // "Text" => Text
}
asColumns[Index] = asColumns[Index].Replace(Escape + Escape, Escape); // Remove double quotes ('My ""special"" text' => 'My "special" text')
if (asColumns[Index] == null) asColumns[Index] = "";
}
The output array is asColumns

Categories

Resources