convert comma separated string to list using linq - c#

I have 3 comma separated strings FirstName, MiddleInitial, LastName
I have a class NameDetails:
public class NameDetails
{
public string FirstName { get; set; }
public string MiddleInitial { get; set; }
public string LastName { get; set; }
}
I have the values for strings as:
FirstName ="John1, John2, John3"
MiddleInitial = "K1, K2, K3"
LastName = "Kenndey1, Kenndey2, Kenndey3"
I need to fill the NameDetails List with the values from the comma separated strings.
Any linq for this? I need this for my asp.net mvc (C#) application.

I don't neccesarily advocate this as a good solution but it does what you asked, which is to 'do it in LINQ'.
It is also probably not the most efficient solution.
string FirstName ="John1, John2, John3";
string MiddleInitial = "K1, K2, K3";
string LastName = "Kenndey1, Kenndey2, Kenndey3";
List<String> fn = new List<String>(FirstName.Split(','));
List<String> mi = new List<String>(MiddleInitial.Split(','));
List<String> ln = new List<String>(LastName.Split(','));
IEnumerable<NameDetails> result = from f in fn
join i in mi on fn.IndexOf(f) equals mi.IndexOf(i)
join l in ln on fn.IndexOf(f) equals ln.IndexOf(l)
select new NameDetails {f, i, l};
I used LINQPad to try this out first (with an anonymous class, not the NameDetails calss).

You can use the Linq to CSV library.

Further to my previous answer you could also try:
// some setup
string firstName ="John1, John2, John3";
string middleInitial = "K1, K2, K3";
string lastName = "Kenndey1, Kenndey2, Kenndey3";
var fn = firstName.Split(',');
var mi = middleInitial.Split(',');
var ln = lastName.Split(',');
// the important bit
var s = fn.Select((f, index) => new NameDetails {f, i = mi[index], l = ln[index]});
It will be fragile to the string arrays having unequal numbers of entries.
Credit due to a previous answer on SO.

Related

Error when trying to List.Sort();

I have this method that creates and returns a list of strings and then should sort the strings alphabetically. I get an error (Cannot implicitly convert type void to System.Collections.Generic.List<string>) when I try this code:
public static List<string> ReturnListofFirstandLastName()
{
List<string> names = new List<string>();
Reademployeelist();
for (int i =0; i < employeelist.Count;i++)
{
names.Add(employeelist[i].first_name + " " + employeelist[i].last_name);
}
return names.Sort();
}
The problem here is that Sort will simply sort the IEnumerable, but it does not return anything (which is different than OrderBy(), which returns a new IEnumerable).
The easiest way to solve this would be to just call Sort on the list, and then return it:
// Previous code omitted
names.Sort();
return names;
}
As a side note, you might want to consider renaming some of your objects. For starters, property names are typically PascalCase (not words separated by underscores). So your employee class wouldn't have a first_name, but instead FirstName.
For example:
public class Employee
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
Also, your employeelist can just be called employees (typically collection types are simply named the plural of what the contained type represents), and Reademployeelist might be better named something like PopulateEmployees (reading implies that it reads the list, but since you call this before iterating over the list it appears that it's actually populating the list)?
private static List<Employee> employees = new List<Employee>();
private static void PopulateEmployees()
{
employees = new List<Employee>
{
new Employee {FirstName = "Warren", LastName = "Buffett"},
new Employee {FirstName = "Jeff", LastName = "Bezos"},
new Employee {FirstName = "Larry", LastName = "Page"},
new Employee {FirstName = "Mark", LastName = "Zuckerberg"},
new Employee {FirstName = "Elon", LastName = "Musk"},
new Employee {FirstName = "Steve", LastName = "Jobs"},
new Employee {FirstName = "Oprah", LastName = "Winfrey"},
new Employee {FirstName = "Howard", LastName = "Schultz"},
new Employee {FirstName = "Larry", LastName = "Ellison"},
new Employee {FirstName = "Satya", LastName = "Nadella"},
};
}
And your method could be named GetEmployeeFirstAndLastNames, and could be simplified a little if we use some System.Linq methods like Select (to select the concatenation of first and last name from each employee), and OrderBy (which will implicitly create a new list instead of us having to do it, and we can return it's result):
public static List<string> GetEmployeeFirstAndLastNames()
{
PopulateEmployees();
return employees.Select(e => e.FirstName + " " + e.LastName)
.OrderBy(name => name)
.ToList();
}
Usage example:
private static void Main()
{
foreach (string name in GetEmployeeFirstAndLastNames())
{
Console.WriteLine(name);
}
GetKeyFromUser("\nDone! Press any key to exit...");
}
Output

How to split string before Binding in repeater

I have a Linq query like this:
var result = from c in db.Class
join s in db.Students on c.Cls_Id equals s.Cls_Id
select new
{
s.Stud_Id,
s.FirstName,
c.Cls_Id,
c.Room,
c.Notification
};
repeater.DataSource = result.ToList();
repeater.DataBind();
But in Notification field has content like this: This Room of C Programming Class/NTFF. If binding in Lable Text='<%#DataBinder.Eval(Container.DataItem, "Notification")%>' it will display: This Room of C Programming Class/NTFF.
I want to split this string into 2 string like this:
str1 = This Room of C Programming Class;
str2 = NTFF;
before binding and binding str1 into Lable1 and str2 into Lable2. How can I do this?
You could use something like this: First create a DTO to store the result entities with all the fields plus one extra field to store the the list of notifications.
public class Result
{
public int Stud_Id { get; set; }
...
...
public string Notification { get; set; }
public string[] Notifications { get; set; }
}
List<Result> result = from c in db.Class
join s in db.Students on c.Cls_Id equals s.Cls_Id
select new Result
{
Stud_Id = s.Stud_Id,
...
...
Notification = c.Notification
}).ToList();
result.ForEach(r =>
{
r.Notifications = r.Notification.Split('/');
});
Now you have two strings in Notifications:
Notification[0] = "This Room of C Programming Class";
Notification[1] = "NTFF"
You can now use whichever you want to bind in the Lable.
You can use Split function to get str1 like this:-
var result = from c in db.Class
join s in db.Students on c.Cls_Id equals s.Cls_Id
select new
{
s.Stud_Id,
s.FirstName,
c.Cls_Id,
c.Room,
str1 = c.Notification.Split('/').FirstOrDefault()
};
Then, you can bind it to your Label like this:-
<asp:Lable Text='<%#DataBinder.Eval(Container.DataItem, "str1")%>'><asp:Label/>
Update:
Since you are using Entity Framework, you can't use Split function directly. You need to bring the results in memory. One way is to create a custom class and fill it like this:-
public class Students
{
public int Stud_Id { get; set; }
public string FirstName{ get; set; }
public int Cls_Id{ get; set; }
public string Room{ get; set; }
public string Notification{ get; set; }
public string str1{ get; set; }
public string str2{ get; set; }
}
Then, first fill your custom class with query like this:-
List<Students> students = (from c in db.Class
join s in db.Students on c.Cls_Id equals s.Cls_Id
select new Students
{
Stud_Id = s.Stud_Id,
FirstName = s.FirstName,
Cls_Id = c.Cls_Id,
Room = c.Room,
Notification= c.Notification
}).ToList();
Finally, iterate through the result and fill up the str1 & str2 variables like this:-
foreach (Student student in students)
{
string[] Notifications = student.Notification.Split('/');
student.str1 = Notifications.FirstOrDefault();
student.str2 = Notifications.ElementAtOrDefault(1);
}
After this, simply bind your labels with parameters str1 & str2.
Use string.Replace() like below:
<%# ((string)DataBinder.Eval(Container.DataItem, "Notification")).Replace("/NTFF", string.Empty) %>
Please check the syntax first. But should work in this case. Let me know if its not working.
Edit:
Code Behind:
var result = from c in db.Class
join s in db.Students on c.Cls_Id equals s.Cls_Id
select new
{
Id = s.Stud_Id,
FirstName = s.FirstName,
ClassId = c.Cls_Id,
Room = c.Room,
FirstNotification = c.Notification.Split('/')[0],
SecondNotification = c.Notification.Split('/')[1]
};
Then on front end use FirstNotification and SecondNotification properties.
Note: Above code will throw Index out of bound exception when there is no '/' character.

Create a tab delimited string from a list of object

I have a list of objects call Person I would like to create a tab delimited string from the list
Example:
public class Person
{
public string FirstName { get; set; }
public int Age { get; set; }
public string Phone { get; set; }
}
List<Person> persons = new List<Persons>();
persons.add ( new person {"bob",15,"999-999-0000"} )
persons.add ( new person {"sue",25,"999-999-0000"} )
persons.add ( new person {"larry",75,"999-999-0000"} )
I would like to output that list to a string that would look like this:
"bob\t15\t999-999-0000\r\nsue\t25\999-999-0000\r\nlarry\t75\999-999-0000\r\n"
right now I was just going to loop through the list and do it line by line the old fashion way.. I was wondering if the was a short cut in LINQ.
Aggregate formatted person strings with StringBuilder. Thus you will avoid creating lot of strings in memory:
var result = persons.Aggregate(
new StringBuilder(),
(sb, p) => sb.AppendFormat("{0}\t{1}\t{2}\r\n", p.FirstName, p.Age, p.Phone),
sb => sb.ToString());
You can Use Strig.Join
string str = string.Join(Environment.NewLine, person.Select(r=> r.FirstName +#"\t" +
r.Age + #"\t" +
r.Phone"))
persons.ForEach(q => output+=(q.firstname+"\\"+q.Age.ToString()+"\\"+q.Phone+"\\"));

parse a string with name-value pairs

How can I parse the following string of name-value pair in C#:
string studentDetail = "StudentId=J1123,FirstName=Jack,LastName=Welch,StudentId=k3342,FirstName=Steve,LastName=Smith"
The purpose of parsing this array is to insert values in DB using Linq to SQL:
[HttpPost]
public ActionResult SaveStudent(string studentDetail)
{
DataContext db = new DataContext();
Student student = new Student();
{
student.StudentID = //StudentID
student.FirstName = //FirstName
student.LastName = //LastName
};
db.Student.InsertOnSubmit(student);
db.SubmitChanges();
return View();
}
What is the best way of approaching this?
You can split on the comma, then on the equals sign. I put the data into a dictionary for easy access.
string input = "StudentId=J1123,FirstName=Jack,LastName=Welch";
Dictionary<string,string> keyValuePairs = input.Split(',')
.Select(value => value.Split('='))
.ToDictionary(pair => pair[0], pair => pair[1]);
string studentId = keyValuePairs["StudentId"];
Note that this isn't validating the input at all to ensure that there are no commas in values, no keys without values, missing keys, etc.
Because the individual student records are not delimited in the input, I would do something like the following:
public class Student
{
public string Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
and then:
private List<Student> DoSplit(string input)
{
var theReturn = new List<Student>();
input = input.Replace(",StudentId=", "|,StudentId=");
var students = input.Split('|');
foreach (var student in students)
{
var attribs = student.Split(',');
if (attribs.Count() == 3)
{
var s = new Student();
s.Id = attribs[0].Substring(attribs[0].LastIndexOf('='));
s.FirstName = attribs[1].Substring(attribs[1].LastIndexOf('='));
s.LastName = attribs[2].Substring(attribs[2].LastIndexOf('='));
theReturn.Add(s);
}
}
return theReturn;
}
Again, it's a bit naive because if content contains "=", ",", or "|", there will be failures. You should add some checking in there as well.
Eric Petroelje had a very nice answer at https://stackoverflow.com/a/2049079/59996
Try System.Web.HttpUtility.ParseQueryString, passing in everything
after the question mark. You would need to use the System.Web
assembly, but it shouldn't require a web context.
(I'm not sure why these two questions aren't linked)
I was able to parse a string of the form a=1&b=2&c=3 using the following code
NameValueCollection nameValueCollection = HttpUtility.ParseQueryString(submission);

convert string data array to list

i have an string data array which contains data like this
5~kiran
2~ram
1~arun
6~rohan
now a method returns an value like string [] data
public string [] names()
{
return data.Toarray()
}
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
List<Person> persons = new List<Person>();
string [] names = names();
now i need to copy all the data from an string array to an list
and finally bind to grid view
gridview.datasoutrce= persons
how can i do it. is there any built in method to do it
thanks in advance
prince
Something like this:
var persons = (from n in names()
let s = n.split('~')
select new Person { Name=s[1], Age=int.Parse(s[0]) }
).ToList();
var persons = names.Select(n => n.Split('~'))
.Select(a => new Person { Age=int.Parse(a[0]), Name=a[1] })
.ToList();
Assuming that the source data are completely valid (i.e. no negative ages, names do not contain '~', every line has both age and name, and so on), here's a very easy implementation:
List<Person> persons = new List<Person>;
foreach (var s in names()) {
var split = s.Split('~');
int age = int.Parse (split[0]);
string name = split[1];
var p = new Person() { Age = age, Name = name };
persons.Add (p);
}
You can also use a Linq query, which is shorter. See Marcelo's Answer for an example.

Categories

Resources