I'm attempting to read a line from a file (csv header) and create a column list that prepends "c[num]_" in front of each column with this code:
int colCount=0;
string line = "col1,col2,col3,col4,col5";
string ColumnList = "([" + (++colCount).ToString() + "_" + line.Replace(",", "],[c" + (++colCount).ToString() + "_") + "]";
I know it's not elegant, but I'm also not sure why my colCount variable doesn't increment inside the replace?? It results with a string like:
([c0_col1],[c1_col2],[c1_col3],[c1_col4],[c1_col5])
The counter increments the first time and then not again inside the replace. Any insights? I think it might be better written with a Regex ReplaceEvaluator but I haven't been able to piece that together yet either.
The paramter of the Replace method is string, and the expression you've entered there is just a string. The count will always be 2. It's not a Func, it a string.
You can use the following Linq to easily achieve the conversion you'd like:
string ColumnList = string.Join(",", line.Split(',').Select((s, i) => $"[c{i + 1}_{s}]"));
Related
Morning folks,
I have an ASP.Net C# page that pulls in a list of servers from a SQL box and displays the list of servers in a label. ("srv1,srv2,srv3"). I need to add double quotes around each of the servers names. ("srv1","srv2","srv3",)
Any help would be greatly appreached.
If you have string
string str = "srv1,srv2,srv3";
Then you can simply do
str = "\"" + str.Replace(",", "\",\"") + "\"";
Now str contains "srv1","srv2","srv3"
As far as I can understand, you are trying to use double quotes in a string.
If you want to use such,
you can use escape character:
("\"srv1\",\"srv2\",\"srv3\"",)
for the sake of simplicity, you can even convert it to a function:
private string quoteString(string serverName){
return "\"" + serverName + "\"";
}
Also, if you have already "srv1,srv2,srv3" format, find ',' characters in the string and add " before and after comma. Also, notice that you should add to first index and last index ".
I have a loop, which writes the values of an array into a .csv file. It is appending each line, so it writes the values vertically, however, I would like it to write each value in a different column rather than by line, that way I can filter the content after running the program.
My initial thought was to save all the values in one variable and then just write the variable to the .csv file, but I believe this would fill all values into one cell instead of distributing them to different columns.
I need it to write all of the values of the array on each loop, and then move to the next line on the each time it loops if that makes sense.
string pathCleansed = #"myfilename.csv";
string[] createText = {
resCleansedMulti.TaxAreaResult[0].PostalAddress[0].StreetAddress1,
resCleansedMulti.TaxAreaResult[0].PostalAddress[0].StreetAddress2,
resCleansedMulti.TaxAreaResult[0].PostalAddress[0].SubDivision,
resCleansedMulti.TaxAreaResult[0].PostalAddress[0].City,
resCleansedMulti.TaxAreaResult[0].PostalAddress[0].PostalCode,
resCleansedMulti.TaxAreaResult[0].PostalAddress[0].MainDivision,
resCleansedMulti.TaxAreaResult[0].confidenceIndicator
};
File.AppendAllLines(pathCleansed, createText, System.Text.Encoding.UTF8);
These are the current results: current results
This is what I would like it to do: desired results
I have had good success with CsvHelper package. You can find more information about it here https://joshclose.github.io/CsvHelper/api/CsvHelper/CsvWriter/.
This helper implements IDisposable so be sure to dispose if it when you're done or wrap it in a using which is more preferred. You will have to provide a writer object to CsvHelper. In the past I've used MemoryStream and StreamWriter.
//Headers if you want
csvWriter.WriteField("StreetAddress1");
csvWriter.WriteField("StreetAddress2");
csvWriter.WriteField("subDivision");
csvWriter.WriteField("City");
csvWriter.WriteField("PostalCode");
csvWriter.WriteField("MainDivision");
csvWriter.WriteField("ConfidenceIndicator");
csvWriter.NextRecord();
//Your Loop Here
{
csvWriter.WriteField(resCleansedMulti.TaxAreaResult[0].PostalAddress[0].StreetAddress1);
csvWriter.WriteField(resCleansedMulti.TaxAreaResult[0].PostalAddress[0].StreetAddress2);
csvWriter.WriteField(resCleansedMulti.TaxAreaResult[0].PostalAddress[0].SubDivision);
csvWriter.WriteField(resCleansedMulti.TaxAreaResult[0].PostalAddress[0].City);
csvWriter.WriteField(resCleansedMulti.TaxAreaResult[0].PostalAddress[0].PostalCode);
csvWriter.WriteField(resCleansedMulti.TaxAreaResult[0].PostalAddress[0].MainDivision);
csvWriter.WriteField(resCleansedMulti.TaxAreaResult[0].confidenceIndicator);
csvWriter.NextRecord();
}
Update: I was able to get the desired results by changing to code to:
string pathCleansed = #"myfilename.csv";
string[] createText = {
resCleansedMulti.TaxAreaResult[0].PostalAddress[0].StreetAddress1 + "," +
resCleansedMulti.TaxAreaResult[0].PostalAddress[0].StreetAddress2 + "," +
resCleansedMulti.TaxAreaResult[0].PostalAddress[0].SubDivision + "," +
resCleansedMulti.TaxAreaResult[0].PostalAddress[0].City + "," +
resCleansedMulti.TaxAreaResult[0].PostalAddress[0].PostalCode + "," +
resCleansedMulti.TaxAreaResult[0].PostalAddress[0].MainDivision + "," +
resCleansedMulti.TaxAreaResult[0].confidenceIndicator
};
File.AppendAllLines(pathCleansed, createText, System.Text.Encoding.UTF8);
I have a bunch of string which i loop through . I want to insert an apostrophe when ever an apostrophe in any string that has apostrophe. I simply do something like below.
string strStatus = "l'oreal";
index = strStatus.IndexOf("'");
strStatus.Insert(index, " ' ");
I want to have output like l''oreal. Yet this fails. I tried using escape patter
strStatus.Insert(index, " \' ");
All to no avail. Please how do i achieve this? Any suggestion/help is highly appreciated.
Strings are immutable. Insert returns a new string with the 2 apostrophes, it doesn't modify strStatus in any way. Your code simply discards the result of Insert.
You should try:
string strStatus = "l'oreal";
index = strStatus.IndexOf("'");
string newStatus=strStatus.Insert(index, "'");
Strings are immutable in .NET (and Java), which means Insert does not modify strStatus, instead it will return a new instance which has the modification you're after.
Do this:
String status = "L'Oreal";
status = status.Insert( status.IndexOf('\''), "'" );
Strings are immutable in C#, so all it's methods do not modify the string itself - they return modified copy. This should work:
strStatus = strStatus.Insert(index, " ' ");
I have a method that copies selected image from an OpenFileDialog to a defined location, and I want to check if an image with the same name exists, and if so to change the name on the fly.
Here is my method:
public void SaveImage(IList<AppConfig> AppConfigs, string ImageNameFilter)
{
string imgPath = AppConfigs[0].ConfigValue.ToString();
Int32 i = 0;
StringBuilder sb = new StringBuilder(selectedFileName);
while (File.Exists(imgPath + "\\" + ImageNameFilter + selectedFileName))
{
sb.Insert(i, 0);
i++;
//ImageNameFilter += (i++).ToString();
}
File.Copy(selectedFile, imgPath + "\\" + ImageNameFilter + selectedFileName);
}
ImageNameFilter is a custom filter that is added at the beginning of each image and the users need this prefix to be able to recognize what the image is used for, only by seeing the prefix. selectedFileName is the name of the image taken with SafeFileName, which means it looks like this - imageName.jpeg.
There are several problems that I have with this code. Firstly, I wanted to change the name like this - imageName1.jpeg, imageName2.jpeg, imageName3.jpeg...imageName14.jpeg.., but if I'm using selectedFileName with the += everything is added, even after the .jpeg, which is not what I want. The only solution that I can think of is to use regex, but I really want to find another way.
Also, incrementing i++ and adding it with += leads to unwanted result which is :
imageName1.jpeg, imageName12.jpeg, imageName123.jpeg...imageName1234567.jpeg.
So, how can I get the result I want and the compromise I see here is to add underscore _ right after the ImageNameFilter and then add i at the beginning of selectedFileName rather in the end as it is by default. But adding something to the beginning of the string is also something I don't know how to do. As you may see I tried StringBuiledr + Insert, but I don't get the expected result.
Basically you need to separate the base file name from the extension (use the helpful methods on Path to do this) before starting the loop, and then keep producing filenames. Each candidate will not be produced based on the last one (it's just based on fixed information and the current iteration count), so you don't need to involve a StringBuilder at all.
Here's one neat way to do it in two steps. First, set up the bookkeeping:
var canonicalFileName = ImageNameFilter + selectedFileName;
var baseFileName = Path.GetFileNameWithoutExtension(canonicalFileName);
var extension = Path.GetExtension(canonicalFileName);
Then do the loop -- here I 'm using LINQ instead of a loop statement because I can, but there's no essential difference from a stock while loop:
var targetFileName = Enumerable.Range(1, int.MaxValue - 1)
.Select(i => Path.Combine(imgPath, baseFileName + i + extension))
.First(file => !File.Exists(file));
File.Copy(selectedFile, targetFileName);
Use Path.GetFileNameWithoutExtension or String.TrimEnd('.') to get the FileName without extension. You can use FileInfo to get the extension as well.
The string, when displayed looks like: value1, value2, value3, value4, value5 etc..
What I want the string to do once I display it is (removing spaces and commas, i assume I can use index + 2 or something to get past the comma):
value1
value2
etc...
lastKnownIndexPos = 0;
foreach (System.Text.RegularExpressions.Match m in System.Text.RegularExpressions.Regex.Matches(unformatedList, ",?")) //Currently is ',' can I use ', '?
{
list += unformatedList.Substring(lastKnownIndexPos, m.Index - 1) + "\n\n"; //-1 to grab just the first value.
lastIndex = m.Index + 2; //to skip the comma and the space to get to the first letter of the next word.
//lastIndex++; //used this to count how many times it was found, maxed at 17 (have over 100):(
}
//MessageBox.Show(Convert.ToString(lastIndex)); //used to display total times each was found.
MessageBox.Show(list);
At the moment the message box does not show any text, but using the lastIndex I get a value of 17 so I know it works for part of it :P
That's easy (I'm using System.Linq here):
var formatted = string.Join("\n\n", unformatedList.Split(',').Select(x => x.Trim()));
MessageBox.Show(formatted);
An alternative approach, as swannee pointed out, would be the following:
var formatted = Regex.Replace(unformatedList, #"\s*,\s*", "\n\n").Trim();
Edit:
To make the above examples work regardless of how you use the result string, you should use Environment.NewLine instead of "\n".
One way is to simply replace the ", " with a newline.
MessageBox.Show( unformatedList.Replace(", ", "\n") );
Or heck, why not just use string.Replace?
var formatted = unformattedList.Replace(", ", "\n\n");