This question already has answers here:
Split a comma separated string while removing whitespace and empty entries
(3 answers)
Closed 9 years ago.
I wanted to format a comma separated string to string with no white spaces, no extra commas and remove empty entries in c#.
string valueString = "sam, mike, , ,john , Tom and Jerry , "
and Expected result is string array with trimmed values as below
string formattedString = "sam, mike, john, Tom and Jerry"
there should be a space after comma (", ") into formatted string
Try this:
string valueString = "sam, mike, , ,john , Tom and Jerry , ";
var nonEmpty = from s in valueString.Split(',')
where !String.IsNullOrWhiteSpace(s)
select s.Trim();
string formattedString = nonEmpty.Join(", ");
Console.WriteLine(formattedString);
var sb = new StringBuilder();
foreach (string s in valueString.Split(new { "," }, StringSplitOptions.RemoveEmptyEntries))
{
sb.Append(s.Trim());
}
string result = sb.ToString();
Try this
string valueString = "sam, mike, , ,john , Tom and Jerry , ";
var strOutput= from s in valueString.Split(',')
where !String.IsNullOrWhiteSpace(s.Trim())
select s.Trim();
string formatString = string.Join(", ", strOutput);
Console.WriteLine(formatString);
yet another variant, now with regex
string valueString = "sam, mike, , ,john , Tom and Jerry , ";
string formattedString = (new Regex(#"(\s*)(?<val>[^,]+)(\s*,)?").Replace(valueString,m=>{
var res = m.Groups["val"].Value.Trim();
return string.IsNullOrEmpty(res)? string.Empty : (res+", ");
})).Trim(", ".ToCharArray());
Related
List<CustomerDetails> customerDetailsList = repo.getCustomerDetails();
Set<String> combinedNamesList = new HashSet<>();
customerDetailsList.forEach(i -> {
combinedNamesList .add((i.getFirstName() != null ? i.getFirstName().toLowerCase(): "") + (i.getLastName() != null ? i.getLastName().toLowerCase(): ""));
});
I would like to create the combinedNamesList in one operation using streams. Each CustomerDetails object has properties for a firstName and LastName. I would like to combine the two properties into a single String in an array such as:
{BobSmith, RachelSnow, DavidJohnson}
Stream the list and filter all customer objetcs having valid firstname and lastname, and then combine the name using String.format
List<String> combinedNamesList = repo.getCustomerDetails()
.stream()
.filter(cust->cust.getFirstName()!=null && cust.getLastName()!=null)
.map(cust->String.format("%s%s",cust.getFirstName(),cust.getLastName()))
.collect(Collectors.toList());
Adding to Deadpool's answer, thinking this might help someone too.
Person p = new Person("Mohamed", "Anees");
Person p1 = new Person("Hello", "World");
Person p2 = new Person("Hello", "France");
System.out.println(
Stream.of(p, p1, p2)
.map(person -> String.join(" ", person.getFirstName(), person.getLastName()))
.collect(Collectors.toSet()));
Here String.join() is used to concatenate names. And, this also produces a more sensible output than the one you are expecting
[Mohamed Anees, Hello World, Hello France]
If you really need names without space, you can replace " " in String.join() delimiter to ""
You can add filter() in the Stream for null checks before converting to lowercase.
enter image description here
How select a name from DATABASE that contains the second letter is "s" using LINQ ?
using lambda expressions:
var str = new string[] { "tsr", "mrg", "d" };
var result = str.Where(s => s.Length>1 && s[1] == 's');
The result variable will contain "tsr" value, and you are checking that the word have at least 2 characters otherwise an Exception would be thrown
from string str in myStrings
where str[1] == 's'
select str
CommaDelimitedStringCollection commaStr = new CommaDelimitedStringCollection();
string itemList = Convert.ToString(HIGList[i].AccountId) + '$' + "HIG" + ',' + '$';
commaStr.Add(itemList);
HigList = HigList + commaStr;
When i am trying to execute this it is showing error like
Value may not contain ','
CommaDelimitedStringCollection is intended to generate a comma delimited string. it means that you add values to it and when you call it's ToString() method, you get the values separated with a comma between each value.
That's why it won't let you add a value with a (non-escaped) comma , in it, as it violates it's very use.
For example:
var csv = new CommaDelimitedStringCollection();
var cities = new[] { "New York", "Log Angeles", "Toronto", "San Francisco" };
foreach (var city in cities)
{
csv.Add(city);
}
Console.WriteLine(csv.ToString()); // will output: New York,Log Angeles,Toronto,San Francisco
And in your case:
CommaDelimitedStringCollection commaStr = new CommaDelimitedStringCollection();
string itemList = Convert.ToString(HIGList[i].AccountId) + '$' + "HIG" + ',' + '$';
commaStr.AddRange(itemList.Split(','));
HigList = HigList + commaStr;
The error message tells you exactly what the problem is and it is immediately visible from the code... You're trying to add a string that contains a comma to a comma delimited string collection. Obviously this makes no sense so an exception is thrown.
i have a simple query in Linq which gets the characters group by word length, below is the code
string sentence = "This is sample linq query";
string[] words = sentence.Split(' ');
var query = from word in words
group word by word.Length into gr
orderby gr.Key ascending
select new { Length = gr.Key, Words = gr };
foreach (var obj in query)
{
Console.WriteLine("Word of Length: {0}", obj.Length);
foreach (string word in obj.Words)
{
Console.WriteLine("{0}", word);
}
Console.WriteLine();
}
it works properly, now i want to convert this into the windows form application by placing the above records into DataGridView, so i implemented like below.
string sentence = "This is sample linq query";
string[] words = sentence.Split(' ');
var query = from word in words
group word by word.Length into gr
orderby gr.Key ascending
select new { Length = gr.Key, Words = gr };
dataGridView1.DataSource = query.ToList();
but here i just gets first coluumn (Length) in the DataGridView and not Words column, is there anything else i need to do to get both columns.
In your case the words-part of the grouping consists of an IGrouping - which cannot be displayed by the datagrid. Try concatenating the words as follows:
var query = from word in words
group word by word.Length into gr
orderby gr.Key ascending
select new { Length = gr.Key, Words = gr.Aggregate((left, right)=>string.Format("{0}, {1}", left, right)) };
Then you will see two columns in the grid, one with the length, the other with the now again concatenated words of that length.
I have a bunch of names in alphabetical order with multiple instances of the same name all in alphabetical order so that the names are all grouped together. Beside each name, after a coma, I have a role that has been assigned to them, one name-role pair per line, something like whats shown below
name1,role1
name1,role2
name1,role3
name1,role8
name2,role8
name2,role2
name2,role4
name3,role1
name4,role5
name4,role1
...
..
.
I am looking for an algorithm to take the above .csv file as input create an output .csv file in the following format
name1,role1,role2,role3,role8
name2,role8,role2,role4
name3,role1
name4,role5,role1
...
..
.
So basically I want each name to appear only once and then the roles to be printed in csv format next to the names for all names and roles in the input file.
The algorithm should be language independent. I would appreciate it if it does NOT use OOP principles :-) I am a newbie.
Obviously has some formatting bugs but this will get you started.
var lastName = "";
do{
var name = readName();
var role = readRole();
if(lastName!=name){
print("\n"+name+",");
lastName = name;
}
print(role+",");
}while(reader.isReady());
This is easy to do if your language has associative arrays: arrays that can be indexed by anything (such as a string) rather than just numbers. Some languages call them "hashes," "maps," or "dictionaries."
On the other hand, if you can guarantee that the names are grouped together as in your sample data, Stefan's solution works quite well.
It's kind of a pity you said it had to be language-agnostic because Python is rather well-qualified for this:
import itertools
def split(s):
return s.strip().split(',', 1)
with open(filename, 'r') as f:
for name, lines in itertools.groupby(f, lambda s: split(s)[0])
print name + ',' + ','.join(split(s)[1] for s in lines)
Basically the groupby call takes all consecutive lines with the same name and groups them together.
Now that I think about it, though, Stefan's answer is probably more efficient.
Here is a solution in Java:
Scanner sc = new Scanner (new File(fileName));
Map<String, List<String>> nameRoles = new HashMap<String, List<String>> ();
while (sc.hasNextLine()) {
String line = sc.nextLine();
String args[] = line.split (",");
if (nameRoles.containsKey(args[0]) {
nameRoles.get(args[0]).add(args[1]);
} else {
List<String> roles = new ArrayList<String>();
roles.add(args[1]);
nameRoles.put(args[0], roles);
}
}
// then print it out
for (String name : nameRoles.keySet()) {
List<String> roles = nameRoles.get(name);
System.out.print(name + ",");
for (String role : roles) {
System.out.print(role + ",");
}
System.out.println();
}
With this approach, you can work with an random input like:
name1,role1
name3,role1
name2,role8
name1,role2
name2,role2
name4,role5
name4,role1
Here it is in C# using nothing fancy. It should be self-explanatory:
static void Main(string[] args)
{
using (StreamReader file = new StreamReader("input.txt"))
{
string prevName = "";
while (!file.EndOfStream)
{
string line = file.ReadLine(); // read a line
string[] tokens = line.Split(','); // split the name and the parameter
string name = tokens[0]; // this is the name
string param = tokens[1]; // this is the parameter
if (name == prevName) // if the name is the same as the previous name we read, we add the current param to that name. This works right because the names are sorted.
{
Console.Write(param + " ");
}
else // otherwise, we are definitely done with the previous name, and have printed all of its parameters (due to the sorting).
{
if (prevName != "") // make sure we don't print an extra newline the first time around
{
Console.WriteLine();
}
Console.Write(name + ": " + param + " "); // write the name followed by the first parameter. The output format can easily be tweaked to print commas.
prevName = name; // store the new name as the previous name.
}
}
}
}