Split full name into first, last and titles - c#

example of the column
I have a column called FULLNAME which consists of a variation of FIRSTNAME and SURNAME separated by a space, and TITLE, FIRSTNAME and SURNAME, all separated by a space. So for example, I could have JOHN SMITH or DR JOHN SMITH.
I am using C# in Visual Studios.
I loop through each of these as per:
foreach (DataRow dr in spreadsheetdata.Tables["EPABase"].Rows)
And my array for the title is as:
title[0] = "Mr";
title[1] = "Mrs";
title[2] = "Miss";
title[3] = "Ms";
title[4] = "Dr";
title[5] = "Rev";
title[6] = "Hon";
title[7] = "Mx";
title[8] = "Other";
It doesn't matter which way around I work, but it's probably easier to get the SURNAME first because it'll always be the the last set of characters in a string, up to the first space value from the right. If I an get this into it's own string of SURNAME, then remove it from the original FULLNAME string, I can then use my array to see if the first set of characters from the left up to the first space appears in it, and if so use as the TITLE string, but if not, use the remaining string after the deletion of the SURNAME to be the FIRSTNAME string.
Just a bit stuck as to how to achieve the first step of this, getting the SURNAME out. I have tried LASTINDEXOF, but this is an integer value, and I need string.

If you are sure that First name or Last Name don't have space in it, you try something like this:
string[] fullNames = { "John Smith", "Dr John Smith" };
string[] titles = { "Mr", "Mrs", "Dr" };
foreach (var item in fullNames)
{
var details = item.Split(' ');
if (titles.Contains(details[0]))
{
Console.WriteLine($"Title: { details[0]} ");
Console.WriteLine($"First Name: { details[1]} ");
Console.WriteLine($"Last Name: { details[2]} ");
}
else
{
Console.WriteLine($"First Name: { details[0]} ");
Console.WriteLine($"Last Name: { details[1]} ");
}
}

To get the surname you can do something as follows:
foreach (DataRow dr in spreadsheetdata.Tables["EPABase"].Rows)
{
var value = dr["FULLNAME"].ToString();
var elementsOfName = value.Split(" ");
var lastName = elementsOfName[elementsOfName.Length - 1];
Console.WriteLine(lastName);
}

Related

SQLite on C#. Select query does not work with string of letters

I'm learning C# since the past week and databases since a couple of days ago, so if you see something dodgy and you ask yourself "Why did he do that like that?", the answer is probably going to be "Because that's all I know for the moment".
In the title I said "of letters" because if I use a string of numbers, it works.
I have a tiny database with three columns. Id (int), FirstName (text) and LastName (text).
Id is unique, primary key and autoincrements. FirstName is unique. The three are not null.
In that database I have two records:
Id FirstName LastName
3- 6666 2222
4- Test O'Test
This is my method:
public static bool isOnDb(string nombre, string apellido)
{
bool flag = false;
{
try
{
using (IDbConnection cnn = new SQLiteConnection(LoadConnectionString()))
{
string tempName = "Test"; // This is temporarily replacing the argument 'nombre'
int tempNum= 3; // More testing. See below
//cnn.Query<Person>($"select * from Person where FirstName = { tempName }", new DynamicParameters());
// This four lines below are just for testing. They are going to be deleted
var output = cnn.Query<Person>($"select * from Person where FirstName = { tempName }", new DynamicParameters());
var person = output.First();
Console.WriteLine("Funciona");
Console.WriteLine($"{ person.Id } - { person.FullName }");
flag = true;
return flag;
}
}
catch (Exception)
{
Console.WriteLine("Derecho a excepcion");
return flag;
}
}
}
Basically, if tempName = "Test", it falls into an exception. But if tempName = "6666" it returns the row.
I also tried selecting by id. That's why tempNum is there.
int tempNum= 4;
var output = cnn.Query<Person>($"select * from Person where Id = { tempNum }", new DynamicParameters());
Well in SQLite the strings are signified by '' so when you pass FirstName = { tempName } and its FirstName = Test it looks for the column called Test in Table person rather than equating it to the 'Test' string
So you can do:
var output = cnn.Query<Person>($"select * from Person where FirstName = '{ tempName }'");
Or better yet:
var people = cnn.Query<Person>("SELECT * FROM PERSON WHERE FirstName = #FirstName", new { FirstName = tempName });

how to split a string array after a fixed length

I have listbox userOptions of object type giving me a result as
{ Number = 1, FName = "ABC", LName = "D" }
{ Number = 2, FName = "EFG", LName = "E" }
{ Number = 3, FName = "HIJ", LName = "F" }
{ Number = 4, FName = "ABC", LName = "G" }
and need to store in a string array just the FName information like
string[] data = new string[3];
string data[0]=ABC
string data[1]=EFG
string data[2]=HIJ
Also to remove the duplicate data from FName too;
I tried with the following code ,but it is time consuming as i cant split the string array data from FName = "ABC" to just 'ABC'
for (int i = 0; i < userOptions.Count; i++)
{
foreach (object items in userOptions)
{
devicedata = userOptions[i].ToString();
string[] Arr = devicedata .Split(',');
devdata[i] = Arr[1];
}
}
here devicedata gives me this information { Number = 1, FName = "ABC", LName = "D" }
Arr splits the data as FName = "ABC" and stores in devdata[i]
how can i merge my above two code so that i can directly get the distinct data like
string data[0]= ABC
string data[1]= EFG
string data[2]= HIJ
If you are really getting JSON (which is weird) you could also just use a regular expression for a fairly simple solution.
Ungreedy:
FName = "(.*)"
Example:
https://regex101.com/r/pCwz3r/1

Splitting a string after the last space

Iam making a program that syncs to a DB, and it takes in names, so i want to split the parsed in string into 2 strings after the last "space".
e.g. splitting the name "John Doe Jackson" into:
john Doe and Jackson
so far what ive done i getting the last name:
public static string getLastName(string fullname)
{
string lastName = fullname.Split(' ').LastOrDefault();
}
how to return the rest of the string so i have something like:
firstName: John Doe
lastName: Jackson
EDIT: made it by doing it like this, isnt the cleanest way, but it gets the job done!
public static string getLastName(string fullname)
{
string lastName = fullname.Split(' ').LastOrDefault();
Console.WriteLine(lastName);
return lastName;
}
public static string getFirstName(string fullname)
{
var parts = fullname.Split(' ');
var lastName = parts.LastOrDefault();
var firstName = string.Join(" ", parts.Take(parts.Length - 1));
return firstName;
}
You could try something like this:
var parts = fullname.Split(' ');
var lastName = parts.LastOrDefault();
var firstName = string.Join(" ",parts.Take(parts.Length-1));
I'd do:
var lastSpaceIndex = fullName.LastIndexOf(' ');
var firstName = fullName.Substring(0, lastSpaceIndex);
var lastName = fullName.Substring(lastSpaceIndex+1);
See it in action here
You can use string.Join
public static string getFirstName(string fullname)
{
return string.join(" ",fullname.Split(' ').Take(fullname.Split(' ').Count()-1));
}
Another version based on accepted answer but protecting for string null/empty and in case of no spaces in fullName leaving input as firstName
if (string.IsNullOrWhiteSpace(fullName))
return new KeyValuePair<string, string>(string.Empty, string.Empty);
var parts = fullName.Trim().Split(' ');
if (parts.Length == 1)
return new KeyValuePair<string, string>(parts[0], string.Empty);
var firstName = string.Join(" ", parts.Take(parts.Length - 1));
var lastName = parts.LastOrDefault();
return new KeyValuePair<string, string>(firstName, lastName);
string name = "John Doe Jackson";
var names = name.Split(' ');
string firstname = names[0] + " " + names[1];
string lastname = names[2];

If statement that is never called

I have this piece of code
Category featured = new Category()
{
active = true,
Categories = new Category[0],
description = "",
identifier = "featured",
name = "Featured",
Products = new Product[0],
url = siteUrl,
};
StatisticCounters.CategoriesCounter();
then below this I have this code.
private IList<Category> FeatureSubCategories(HtmlNode std, Category category,Category featured)
{
List<Category> categories = new List<Category>();
{
if (category.name == "Featured")
{
var nodes = std.SelectNodes("//span[contains(#class,'widget')] [position() <= 4]"); //TODO
foreach (var node in nodes)
{
string name = SiteParserUtilities.ParserUtilities.CleanText(System.Net.WebUtility.HtmlDecode(node.InnerText));
string url = node.Attributes["href"].Value;
string identifier = url.Split('/').Last().Replace(".html", "");
WriteQueue.write(string.Format(" Category [{0}].. {1} ", name, url));
IList<Category> sub = GetSubCategories(std);
Category c = new Category()
{
active = true,
Categories = sub.ToArray(),
description = "",
identifier = identifier,
name = name,
Products = new Product[0],
url = url,
};
StatisticCounters.CategoriesCounter();
categories.Add(c);
}
}
}
return categories;
}
for some reason tho when I run the code the if statement if (category.name == "Featured") is never called and I am not sure why this is. To start to parse the xpath and store them links into an array. Thank you for any help which you can give.
It is best to check in debugger. Some times whites spaces cause the problem. It is simple mistake done by many programmers. When we get data from database, there may be some leading spaces. When we compare with some value (thinking that there is no leading space), it will not compare without trimming those spaces. For example
string s1 = "TEST";
string s2 = " TEST";
if (s1 == s2) {
Console.WriteLine("Equal");
}
Please use trim function to remove any white spaces and compare.

Check if a string contains a value within a generic list and replace it

I have a string with a message containing some fields I want to swap out to actual values
var message = "Hi [CustomerName]. Its [TODAY], nice to see you were born on the [DOB]!";
var mappingCodes = new List<string> {"[CUSTOMER_NAME]","[DOB]",[TODAY]};
var customEmails = new Dictionary<string, string>();
var today = DateTime.Now;
var customers = new List<Customer>()
{
new Customer()
{
FirstName = "Jo",
LastName = "Bloggs",
Email = "jo#bloggs.com",
DOB = "10/12/1960"
}
};
foreach (var customer in customers)
{
var emailMessage = "";
customEmails.Add(customer.Email,emailMessage);
}
What I'm trying to do is loop through each of the customers and take the message replacing any of the mappingCodes with actual codes.
e.g. [Today] Would be the today and CustomerName would be Customer.FirstName + Customer.LastName
There could be 1000's of customers so I need something robust. I'm just not sure how to first check the string contains any of the mappingCodes and then replace them with the desired values.
Any advice?
You could try something like this. String.Format is rather efficient. It also would allow you to format Date.Today, if you want.
var customers = new List<Customer>()
{
new Customer()
{
FirstName = "Jo",
LastName = "Bloggs",
Email = "jo#bloggs.com",
DOB = "10/12/1960"
}
};
foreach (var customer in customers)
{
var emailMessage = String.Format("Hi {0}. Its {1}, nice to see you were born on the {2}!", customer.FirstName, DateTime.Today, customer.DOB);
customEmails.Add(customer.Email,emailMessage);
}
You can use Regex.Replace(string, MatchEvaluator):
var customers = new[] {
new {
Name = "Fred Flintstone",
City = "Bedrock"
},
new {
Name = "George Jetson",
City = "Orbit City"
}
};
string template = "Hello, [NAME] from [CITY]!";
var re = new Regex(#"\[\w+\]"); // look for all "words" in square brackets
foreach (var customer in customers)
{
Trace.WriteLine(
re.Replace(template, m => {
// determine the replacement string
switch (m.Value) // m.Value is the substring that matches the RE.
{
// Handle getting and formatting the properties here
case "[NAME]":
return customer.Name;
case "[CITY]":
return customer.City;
default:
// The "mapping code" is not supported, I just return the
// original substring
return m.Value;
}
}));
}
Obviously the above is just the general approach, you'll have to modify it to support your mapping codes and data structures.

Categories