I have a requirement to get the first letter of the first, middle and last names. It is working if each of the fields contain value. But the middle name is nullable field. So i'm getting error if the value of middle name is null.
(from P in this._dbContext.Person
where P.PersonIndex == personIndex
select new PersonInitialsDTO
{
PersonIndex = P.PersonIndex,
PersonInitials = string.Format("{0}{1}{2}", P.FirstName.ToUpper().First(), P.MiddleName.ToUpper().First(), P.LastName.ToUpper().First())
}).FirstOrDefault();
use ? to see if the value is null before executing next methods.
string.Format("{0}{1}{2}", P.FirstName.ToUpper().First(), P.MiddleName?.ToUpper().First(), P.LastName.ToUpper().First())
P.MiddleName?.ToUpper().First() -> If P.MiddleName is null, dont do ToUpper() or any other methods afterwards.
Example of use of ?. in string.format statement.
Pers person = new Pers()
{
First = "First",
Last = "Last"
};
Console.WriteLine(string.Format("{0}{1}{2}", person.First.First(), person.Middle?.ToUpper().First(), person.Last.First()));
// Prints
FL
Requirement: get the first letter of the first, middle and last names.
Well, apparently this requirement is not complete: if one of these names is null or empty, there is no first letter.
Furthermore: if I look at the code, you don't want the first letter, you want a string that contains the first letter.
And why uppercase the complete string if you will only use the first character?
So let's change it slightly:
Requirement: Given three strings: first, middle and last, get me the string that contains the uppercase values of the first character of each of these strings, or String.Empty if the string is null or empty.
"Vincent" "van" "Gogh" => "VVG"
"rembrandt" "van" "rijn" => "RVR"
"Piet" "Mondriaan" => "PM"
From each of these three strings,
Check if if it is null, if so, use Enumerable.Empty<char>
Create a sequence that contains only the first character of the string. So if the string was null or empty, this first character will be an empty sequence of character).
Concatenate these three sequences.
Result: a sequence of characters that contains only the first character of each of these strings, or no character at all if the string was null or empty.
In baby steps, I'll write the type in front, so you can see what happens.
string first = ...
string middle = ...
string last = ...
IEnumerable<char> firstChars = first?.Take(1) ?? Enumerable.Empty<char>(),
IEnumerable<char> midChars = middle?.Take(1) ?? Enumerable.Empty<char>(),
IEnumerable<char> lastChars = last?.Take(1) ?? Enumerable.Empty<char>(),
IEnumerable<char> chars = firstChars.Concat(midChars).Concat(lastChars);
So from our original input examples we have:
Vincent Van Gogh: {'V', 'V', 'G'}
rembrandt van rijn: {'r', 'v', 'r'}
Piet Mondriaan {'p', 'm'}
So all we have to do is to convert them to uppercase and convert to a string:
IEnumerable uppercaseChars = chars.Select(c => Char.ToUpper(c));
Note: until know the query is not executed! I only used methods that use deferred execution!
string result = new string(uppercaseChars.ToArray());
Of course you can write this in one big LINQ statement. I'm not sure if that would improve readability. It won't have any effect on performance.
I tried with below. Now it's working
(from P in this._dbContext.Person
where P.PersonIndex == personIndex
select new PersonInitialsDTO
{
PersonIndex = P.PersonIndex,
PersonInitials = (P.MiddleName == "")
? string.Format("{0}{1}", P.FirstName.ToUpper().First(),
P.LastName.ToUpper().First())
: string.Format("{0}{1}{2}", P.FirstName.ToUpper().First(),
P.MiddleName.ToUpper().First(), P.LastName.ToUpper().First())
}).FirstOrDefault();
Related
Using the below code I see the result as
cardetails = "<ul>" + car.model.Product.Replace("•", "<li>").Replace("\n", "</li>") + "</li></ul>";
Strng 1:
"Product":"• Hatchback\n• Hyundai"
Hatchback
Hyundai
In the same string I have added Sedan as new type now the complete string is
"Product":"• Hatchback\n• Sedan\n• Hyundai" here I need to skip Hatchback and retrieve only Sedan in First list item using conditional operator
Sedan
Hyundai
cardetails = carType == CarTypes.Hatchback.ToString()
? "<ul>" + car.model.Product.Replace("•", "<li>").Replace("\n", "</li>") + "</li></ul>"
: "How to add logic here to retrieve Sedan in first <li> and skip hatchback";
How can I achieve this
I think you are confusing the behaviour of Skip(). I assume that car.model.Product is a string, which means Skip will treat the string as an IEnumerable<char> and therefore Skip(1) will skip one character in the string:
var myString = "this is a string";
var result = myString.Skip(1);
// result == "his is a string"
One way you could solve this is by splitting the string into the parts you are interested in and then skip the first part you want to discard:
var productParts = car.model.Product
// We don't really care about the line breaks
.Replace(#"\n", "")
// Split the string and remove any empty parts and
// remove (trim) spaces from the ends of each part
.Split("•", StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntriesTrimEntries)
// Wrap each part in a <li> tag
.Select(part => $"<li>{part}</li>");
cardetails = carType == CarTypes.Hatchback.ToString()
? $"<ul>{string.Join(Environment.NewLine, productParts)}</ul>"
: $"<ul>{string.Join(Environment.NewLine, productParts.Skip(1))}</ul>";
// Notice: we skip the first (Hatchback) part above
Update: July 26, 2017
I have a string inside which the values are comma separated. However for some cases it is coming double comma ,, at in a consecutive way. But when I am using using string.split(',') it's returning me a array which doesn't have a value on that index. For example
string str = "12,3,5,,6,54,127,8,,0,98,"
It's breaking down the the array this way
str2[0] = 12
str2[1] = 3
str2[2] = 5
str2[3] = ""
str2[4] = 6
str2[5] = 54
str2[6] = 127
str2[7] = 8
str2[8] = ""
str2[9] = 0
str2[10] = 98
str2[11] = ""
Look here I am getting the array with one or more empty value. So I want to put a 0 in each empty position when I am splitting the string. Here I have found something to skip the empty values
str .Split(',', StringSplitOptions.RemoveEmptyEntries)
However I did not found such a solution put a default value at empty index. I have gone through these previous Questions Q1, Q2, But these are not effective for mine. I am using C# for web application in .Net framework
Try the below code:
You can able to use IEnumerable extension method (Select) of String object.
string str = "12,3,5,,6,54,127,8,,0,98";
var strVal = str.Split(',').Select(s => string.IsNullOrWhiteSpace(s) ? "0" : s);
Use the following code to replace empty string to zero
string str = "12,3,5,,6,54,127,8,,0,98";
var a= str.Split(',').Select(x=>string.IsNullOrEmpty(x)?"0":x);
While all the suggested solutions work perfectly, they are all iterating twice your input (once for the string split, once for the string replace or regex, once for the array replace).
Here is a solution iterating only once the input:
var input = "12,3,5,,6,54,127,8,,0,98";
var result = new List<int>();
var currentNumeric = string.Empty;
foreach(char c in input)
{
if(c == ',' && String.IsNullOrWhiteSpace(currentNumeric))
{
result.Add(0);
}
else if(c == ',')
{
result.Add(int.Parse(currentNumeric));
currentNumeric = string.Empty;
}
else
{
currentNumeric += c;
}
}
if(!String.IsNullOrWhiteSpace(currentNumeric))
{
result.Add(int.Parse(currentNumeric));
}
else if(input.EndsWith(","))
{
result.Add(0);
}
You can run your string through regex to put zeros into it before going into Split:
Regex.Replace(str, "(?<=(^|,))(?=(,|$))", "0").Split(',')
The regex will insert zeros into the original string in spots when two commas are next to each other, or when a comma is detected at the beginning or at the end of the string (demo).
How to get whole text from document contacted into the string. I'm trying to split text by dot: string[] words = s.Split('.'); I want take this text from text document. But if my text document contains empty lines between strings, for example:
pat said, “i’ll keep this ring.”
she displayed the silver and jade wedding ring which, in another time track,
she and joe had picked out; this
much of the alternate world she had elected to retain. he wondered what - if any - legal basis she had kept in addition. none, he hoped; wisely, however, he said nothing. better not even to ask.
result looks like this:
1. pat said ill keep this ring
2. she displayed the silver and jade wedding ring which in another time track
3. she and joe had picked out this
4. much of the alternate world she had elected to retain
5. he wondered what if any legal basis she had kept in addition
6. none he hoped wisely however he said nothing
7. better not even to ask
but desired correct output should be like this:
1. pat said ill keep this ring
2. she displayed the silver and jade wedding ring which in another time track she and joe had picked out this much of the alternate world she had elected to retain
3. he wondered what if any legal basis she had kept in addition
4. none he hoped wisely however he said nothing
5. better not even to ask
So to do this first I need to process text file content to get whole text as single string, like this:
pat said, “i’ll keep this ring.” she displayed the silver and jade wedding ring which, in another time track, she and joe had picked out; this much of the alternate world she had elected to retain. he wondered what - if any - legal basis she had kept in addition. none, he hoped; wisely, however, he said nothing. better not even to ask.
I can't to do this same way as it would be with list content for example: string concat = String.Join(" ", text.ToArray());,
I'm not sure how to contact text into string from text document
I think this is what you want:
var fileLocation = #"c:\\myfile.txt";
var stringFromFile = File.ReadAllText(fileLocation);
//replace Environment.NewLine with any new line character your file uses
var withoutNewLines = stringFromFile.Replace(Environment.NewLine, "");
//modify to remove any unwanted character
var withoutUglyCharacters = Regex.Replace(withoutNewLines, "[“’”,;-]", "");
var withoutTwoSpaces = withoutUglyCharacters.Replace(" ", " ");
var result = withoutTwoSpaces.Split('.').Where(i => i != "").Select(i => i.TrimStart()).ToList();
So first you read all text from your file, then you remove all unwanted characters and then split by . and return non empty items
Have you tried replacing double new-lines before splitting using a period?
static string[] GetSentences(string filePath) {
if (!File.Exists(filePath))
throw new FileNotFoundException($"Could not find file { filePath }!");
var lines = string.Join("", File.ReadLines(filePath).Where(line => !string.IsNullOrEmpty(line) && !string.IsNullOrWhiteSpace(line)));
var sentences = Regex.Split(lines, #"\.[\s]{1,}?");
return sentences;
}
I haven't tested this, but it should work.
Explanation:
if (!File.Exists(filePath))
throw new FileNotFoundException($"Could not find file { filePath }!");
Throws an exception if the file could not be found. It is advisory you surround the method call with a try/catch.
var lines = string.Join("", File.ReadLines(filePath).Where(line => !string.IsNullOrEmpty(line) && !string.IsNullOrWhiteSpace(line)));
Creates a string, and ignores any lines which are purely whitespace or empty.
var sentences = Regex.Split(lines, #".[\s]{1,}?");
Creates a string array, where the string is split at every period and whitespace following the period.
E.g:
The string "I came. I saw. I conquered" would become
I came
I saw
I conquered
Update:
Here's the method as a one-liner, if that's your style?
static string[] SplitSentences(string filePath) => File.Exists(filePath) ? Regex.Split(string.Join("", File.ReadLines(filePath).Where(line => !string.IsNullOrEmpty(line) && !string.IsNullOrWhiteSpace(line))), #"") : null;
I would suggest you to iterate through all characters and just check if they are in range of 'a' >= char <= 'z' or if char == ' '. If it matches the condition then add it to the newly created string else check if it is '.' character and if it is then end your line and add another one :
List<string> lines = new List<string>();
string line = string.Empty;
foreach(char c in str)
{
if((char.ToLower(c) >= 'a' && char.ToLower(c) <= 'z') || c == 0x20)
line += c;
else if(c == '.')
{
lines.Add(line.Trim());
line = string.Empty;
}
}
Working online example
Or if you prefer "one-liner"s :
IEnumerable<string> lines = new string(str.Select(c => (char)(((char.ToLower(c) >= 'a' && char.ToLower(c) <= 'z') || c == 0x20) ? c : c == '.' ? '\n' : '\0')).ToArray()).Split('\n').Select(s => s.Trim());
I may be wrong about this. I would think that you may not want to alter the string if you are splitting it. Example, there are double/single quote(s) (“) in part of the string. Removing them may not be desired which brings up the possibly of a question, reading a text file that contains single/double quotes (as your example data text shows) like below:
var stringFromFile = File.ReadAllText(fileLocation);
will not display those characters properly in a text box or the console because the default encoding using the ReadAllText method is UTF8. Example the single/double quotes will display (replacement characters) as diamonds in a text box on a form and will be displayed as a question mark (?) when displayed to the console. To keep the single/double quotes and have them display properly you can get the encoding for the OS’s current ANSI encoding by adding a parameter to the ReadAllText method like below:
string stringFromFile = File.ReadAllText(fileLocation, ASCIIEncoding.Default);
Below is code using a simple split method to .split the string on periods (.) Hope this helps.
private void button1_Click(object sender, EventArgs e) {
string fileLocation = #"C:\YourPath\YourFile.txt";
string stringFromFile = File.ReadAllText(fileLocation, ASCIIEncoding.Default);
string bigString = stringFromFile.Replace(Environment.NewLine, "");
string[] result = bigString.Split('.');
int count = 1;
foreach (string s in result) {
if (s != "") {
textBox1.Text += count + ". " + s.Trim() + Environment.NewLine;
Console.WriteLine(count + ". " + s.Trim());
count++;
}
else {
// period at the end of the string
}
}
}
I have these data files comming in on a server that i need to split into [date time] and [value]. Most of them are delimited a single time between time and value and between date and time is a space. I already have a program processing the data with a simple split(char[]) but now found data where the delimiter is a space and i am wondering how to tackle this best.
So most files i encountered look like this:
18-06-2014 12:00:00|220.6
The delimiters vary, but i tackled that with a char[]. But today i ran into a problem on this format:
18-06-2014 12:00:00 220.6
This complicates things a little. The easy solution would be to just add a space to my split characters and when i find 3 splits combine the first two before processing?
I'm looking for a 2nd opining on this matter. Also the time format can change to something like d/m/yy and the amount of lines can run into the millions so i would like to keep it as efficient as possible.
Yes I believe the most efficient solution is to add space as a delimiter and then just combine the first two if you get three. That is going to be be more efficient than regex.
You've got a string 18-06-2014 12:00:00 220.6 where first 19 characters is a date, one character is a separation symbol and other characters is a value. So:
var test = "18-06-2014 12:00:00|220.6";
var dateString = test.Remove(19);
var val = test.Substring(20);
Added normalization:
static void Main(string[] args) {
var test = "18-06-2014 12:00:00|220.6";
var test2 = "18-6-14 12:00:00|220.6";
var test3 = "8-06-14 12:00:00|220.6";
Console.WriteLine(test);
Console.WriteLine(TryNormalizeImportValue(test));
Console.WriteLine(test2);
Console.WriteLine(TryNormalizeImportValue(test2));
Console.WriteLine(test3);
Console.WriteLine(TryNormalizeImportValue(test3));
}
private static string TryNormalizeImportValue(string value) {
var valueSplittedByDateSeparator = value.Split('-');
if (valueSplittedByDateSeparator.Length < 3) throw new InvalidDataException();
var normalizedDay = NormalizeImportDayValue(valueSplittedByDateSeparator[0]);
var normalizedMonth = NormalizeImportMonthValue(valueSplittedByDateSeparator[1]);
var valueYearPartSplittedByDateTimeSeparator = valueSplittedByDateSeparator[2].Split(' ');
if (valueYearPartSplittedByDateTimeSeparator.Length < 2) throw new InvalidDataException();
var normalizedYear = NormalizeImportYearValue(valueYearPartSplittedByDateTimeSeparator[0]);
var valueTimeAndValuePart = valueYearPartSplittedByDateTimeSeparator[1];
return string.Concat(normalizedDay, '-', normalizedMonth, '-', normalizedYear, ' ', valueTimeAndValuePart);
}
private static string NormalizeImportDayValue(string value) {
return value.Length == 2 ? value : "0" + value;
}
private static string NormalizeImportMonthValue(string value) {
return value.Length == 2 ? value : "0" + value;
}
private static string NormalizeImportYearValue(string value) {
return value.Length == 4 ? value : DateTime.Now.Year.ToString(CultureInfo.InvariantCulture).Remove(2) + value;
}
Well you can use this one to get the date and the value.
(((0[1-9]|[12][0-9]|3[01])-(0[1-9]|1[012])-(19|20)\d\d)\s((\d{2}:?){3})|(\d+\.?\d+))
This will give you 2 matches
1º 18-06-2014 12:00:00
2º 220.6
Example:
http://regexr.com/391d3
This regex matches both kinds of strings, capturing the two tokens to Groups 1 and 2.
Note that we are not using \d because in .NET it can match any Unicode digits such as Thai...
The key is in the [ |] character class, which specifies your two allowable delimiters
Here is the regex:
^([0-9]{2}-[0-9]{2}-[0-9]{4} (?:[0-9]{2}:){2}[0-9]{2})[ |]([0-9]{3}\.[0-9])$
In the demo, please pay attention to the capture Groups in the right pane.
Here is how to retrieve the values:
var myRegex = new Regex(#"^([0-9]{2}-[0-9]{2}-[0-9]{4} (?:[0-9]{2}:){2}[0-9]{2})[ |]([0-9]{3}\.[0-9])$", RegexOptions.IgnoreCase);
string mydate = myRegex.Match(s1).Groups[1].Value;
Console.WriteLine(mydate);
string myvalue = myRegex.Match(s1).Groups[1].Value;
Console.WriteLine(myvalue);
Please let me know if you have questions
Given the provided format I'd use something like
char delimiter = ' '; //or whatever the delimiter for the specific file is, this can be set in a previous step
int index = line.LastIndexOf(delimiter);
var date = line.Remove(index);
var value = line.Substring(++index);
If there are that many lines and efficiency matters, you could obtain the delimiter once on the first line, by looping back from the end and find the first index that is not a digit or dot (or comma if the value can contain those) to determine the delimiter, and then use something such as the above.
If each line can contain a different delimiter, you could always track back to the first not value char as described above and still maintain adequate performance.
Edit: for completeness sake, to find the delimiter, you could perform the following once per file (provided that the delimiter stays consistent within the file)
char delimiter = '\0';
for (int i = line.Length - 1; i >= 0; i--)
{
var c= line[i];
if (!char.IsDigit(c) && c != '.')
{
delimiter = c;
break;
}
}
I'm working with an entity (Employee) that has 3 fields: FirstName, LastName, & Login
I want to grab the lastname and the first letter of the firstname field and write this to the login field. How do I grab the first letter of the firstname?
Thanks for any help.
Just as simple as:
if (!string.IsNullOrEmpty(Employee.FirstName))
{
string firstLetter = Employee.FirstName.SubString(0, 1);
}
With that you get the first letter as a string and with this the character:
if (!string.IsNullOrEmpty(Employee.FirstName))
{
char firstLetter = Employee.FirstName[0];
}
To get the first character (not necessarily a letter) use an index into the string:
char c = employee.FirstName[0];
You may also want to first check that the string is non-null and non-empty and strip leading whitespace, and that the first character is actually a letter:
if (employee != null && employee.FirstName != null) {
string name = employee.FirstName.TrimStart();
if (name.Length > 0) {
char firstChar = name[0];
if (char.IsLetter(firstChar)) {
employee.Login = firstChar.ToString();
}
}
}
char firstCharOfFirstName = someEmployee.FirstName[0];
If the FirstName field can have leading whitespace you can do:
char firstCharOfFirstName = someEmployee.FirstName.Trim()[0];
(As the other answers mention it's good to check for empty string and null string)
If the first name might be empty, you would have to check that when getting the first letter:
FirstName.Substring(0, Math.Min(FirstName.Length, 1))
This will give you an empty string if the FirstName string is empty, otherwise the first character as a string, so that you can concatenate it with the last name.
Bear in mind, SubString() or FirstName[0] will throw a ArgumentOutOfRangeException or IndexOutOfRangeException if
FirstName == string.Empty
So, this code will at least avoid exception:
if(str2 != null)
{
char result = (str2.Length > 0)
? str2[0]
: (char)0;
}
Don't forget this code will return a false result if the string is empty!