C# Add a blank value in between string in of CSV file - c#

I have this on a string that is generated from a list how can I add a blank value in between the string.
using (var file = File.CreateText()
{
foreach (var permutation in result)
{
file.WriteLine(string.Join(",", permutation));
//i++;
}
}
Here is the result:
string result = A,B,C,D,E,F,G,H,I,J
How can I add a blank value ", ," in the result at a specific index
Example: A,B,C,D,E,F, ,G,H,I,J
Note: result is a permutation and length is not consistent
Result is a IEnumerable can it be split?

You can split your string with the comma as the separator, go through your characters and add them to a list. Add an extra empty string at your desired index and join the data back together. This way you don't have to deal with deciding if you need to add a commar or not when concatenating the strings.
var index = 6;
var data = "A,B,C,D,E,F,G,H,I,J";
var chars = data.Split(new [] { ',' });
List<string> resultData = new List<string>();
var i = 0;
foreach (var c in chars) {
if (i == index) {
resultData.Add(" ");
}
i++;
resultData.Add(c);
}
var result = string.Join(",", resultData.ToArray();

You can use the following basic algorithm to follow your questions code logic:
using (var file = File.CreateText())
{
int i = -1;// Loop counter
int termReplacementIndex = 3;// Input or constant to find letter to replace
foreach (var permutation in result)
{
i++;
if (i == ((termReplacementIndex * 2) - 2))// Only stops on letters not commas
{
file.WriteLine(string.Join(",", " ,"));// Adding of blank " "
}
file.WriteLine(string.Join(",", permutation));// Adding of letter
}
}

If permutation is a list you can just insert a null value at the required index:
using System;
using System.Collections.Generic;
public class Program
{
public static void Main()
{
var list = new List<string>();
list.Add("test 1");
list.Add("test 2");
list.Add("test 3");
list.Insert(2, null);
var str = string.Join(",", list);
Console.WriteLine(str); // test 1,test 2,,test 3
}
}

Modify the Collection before joining it so you wont have to split it and iterate it again.
As the side of permutation vary you could be trying to insert at index X when X is larger greater permutation.Count() instead of an ArgumentOutOfRangeException I decide to add the element at the end. But you will have to define that.
public string CsvProjection(List<string> inputs, int needleIndex, string needleValue)
{
if (needleIndex < 0)
{
throw new ArgumentOutOfRangeException("needleIndex must be positive.");
}
if (needleIndex > inputs.Count())
{//Either throw an exception because out of bound or add to the end
inputs.Add(needleValue);
}
inputs.Insert(needleIndex, needleValue);
return string.Join(",", inputs);
}
Usage simply add the value and the index variable:
var needleIndex= 2;
var needleValue = "My New Value";
using (var file = File.CreateText()
{
foreach (var permutation in result)
{
file.WriteLine(CsvProjection(permutation, needleIndex, needleValue));
}
}

Related

split string in to several strings at specific points

I have a text file with lines of text laid out like so
12345MLOL68
12345MLOL68
12345MLOL68
I want to read the file and add commas to the 5th point, 6th point and 9th point and write it to a different text file so the result would be.
12345,M,LOL,68
12345,M,LOL,68
12345,M,LOL,68
This is what I have so far
public static void ToCSV(string fileWRITE, string fileREAD)
{
int count = 0;
string x = "";
StreamWriter commas = new StreamWriter(fileWRITE);
string FileText = new System.IO.StreamReader(fileREAD).ReadToEnd();
var dataList = new List<string>();
IEnumerable<string> splitString = Regex.Split(FileText, "(.{1}.{5})").Where(s => s != String.Empty);
foreach (string y in splitString)
{
dataList.Add(y);
}
foreach (string y in dataList)
{
x = (x + y + ",");
count++;
if (count == 3)
{
x = (x + "NULL,NULL,NULL,NULL");
commas.WriteLine(x);
x = "";
count = 0;
)
}
commas.Close();
}
The problem I'm having is trying to figure out how to split the original string lines I read in at several points. The line
IEnumerable<string> splitString = Regex.Split(FileText, "(.{1}.{5})").Where(s => s != String.Empty);
Is not working in the way I want to. It's just adding up the 1 and 5 and splitting all strings at the 6th char.
Can anyone help me split each string at specific points?
Simpler code:
public static void ToCSV(string fileWRITE, string fileREAD)
{
string[] lines = File.ReadAllLines(fileREAD);
string[] splitLines = lines.Select(s => Regex.Replace(s, "(.{5})(.)(.{3})(.*)", "$1,$2,$3,$4")).ToArray();
File.WriteAllLines(fileWRITE, splitLines);
}
Just insert at the right place in descending order like this.
string str = "12345MLOL68";
int[] indices = {5, 6, 9};
indices = indices.OrderByDescending(x => x).ToArray();
foreach (var index in indices)
{
str = str.Insert(index, ",");
}
We're doing this in descending order because if we do other way indices will change, it will be hard to track it.
Here is the Demo
Why don't you use substring , example
editedstring=input.substring(0,5)+","+input.substring(5,1)+","+input.substring(6,3)+","+input.substring(9);
This should suits your need.

trying to remove unique words from a string

My code believe needs to remove unique instancs of the same word (Complete word).
What do I mean by complete words. Well, given the following string:
THIIS IS IS A TEST STRRING
I need this returned:
THIIS IS A TEST STRRING
My code returns this:
THIS IS A TEST STRING
var items = sString.Split(' ');
var uniqueItems = new HashSet<string>(items);
foreach (var item in uniqueItems)
{
strBuilder.Append(item);
strBuilder.Append(" ");
}
finalString = strBuilder.ToString().TrimEnd();
How can i therefore, retain an instance of a duplicate characters within a word, but remove complete duplicate words entirley?
You need Split and Distinct
var words = "THIIS IS IS A TEST STRRING".Split(' ').Distinct();
var result = string.Join(" ", words);
bro Call this method i know its a bit complex and lengthy but you will be amazed after getting the results!
public string IdentifySamewords(string str)
{
string[] subs=null;
char[] ch=str.ToCharArray();
int count=0;
for(int i=0;i<ch.Length;i++)
{
if(ch[i]==' ')
count++;
}
count++;
subs=new string[count];
count=0;
for(int i=0;i<ch.Length;i++)
{
if(ch[i]==' ')
count++;
else
subs[count]+=ch[i].ToString();
}
string current=null,prev=null,res=null;
for(int i=0;i<subs.Length;i++)
{
current=subs[i];
if(current!=prev)
res+=current+" ";
prev=current;
}
return res;
}

Counting occurrences in Array

I am counting the occurrence of each element in the array but I get the error "Value cannot be null" This doesn't make sense to me because arr1 is fully populated with no null values except the last 5 elements which are null.
Here is my code. I am using dictionary for the first time so I may have some logic error somewhere. I am reading from a textfile.
string[] arr1 = new string[200];
StreamReader sr = new StreamReader("newWorkSheet.txt");
string Templine1 = "";
int counter = 0;
while (Templine1 != null)
{
Templine1 = sr.ReadLine();
arr1[counter] = Templine1;
counter += 1;
}
sr.Close();
// Dictionary, key is number from the list and the associated value is the number of times the key is found
Dictionary<string, int> occurrences = new Dictionary<string, int>();
// Loop test data
foreach (string value in arr1)
{
if (occurrences.ContainsKey(value)) // Check if we have found this key before
{
// Key exists. Add number of occurrences for this key by one
occurrences[value]++;
}
else
{
// This is a new key so add it. Number 1 indicates that this key has been found one time
occurrences.Add(value, 1);
}
}
// Dump result
System.IO.StreamWriter sr2 = new System.IO.StreamWriter("OrganizedVersion.txt");
foreach (string key in occurrences.Keys)
{
sr2.WriteLine("Integer " + key.ToString() + " was found " + occurrences[key].ToString() + " times");
}
sr2.Close();
Console.ReadLine();
Edit: I put all the code here including declaration.
It's not exactly your question but Linq could reduce the number of lines here:
var groups = arr1.GroupBy(item => item);
foreach (var group in groups)
{
Console.WriteLine(string.Format("{0} occurences of {1}", group.Count(), group.Key);
}
My money is on arr1 being null (based on the fact that you should know the size beforehand but you're filling with lines from a file that could possibly change). The good thing is that you don't actually need it.
Replace this: foreach (string value in arr1)
... with this:
foreach(string value in File.ReadLines("fileName"))
{
}
MSDN File.ReadLines
"arr1 is fully populated with no null values"
Nope. The last item that you put in the array is null. Check the value before you put it in the array:
while (true) {
Templine1 = sr.ReadLine();
if (Templine1 == null) break;
arr1[counter++] = Templine1;
}
Or if you like this method better:
while ((Templine1 = sr.ReadLine()) != null) {
arr1[counter++] = Templine1;
}
Now, loop up to the index counter, instead of looping through the entire array regardless of how many items you put in it:
for (int i = 0; i < counter; i++) {
string value = arr1[i];
...
}
In your loop you need to check if there is null in your value
foreach (string value in arr1)
{
if (!string.IsNullOrEmpty(value))
{
........
This will take care of problems you might have in the file.

summing splitted text from .txt file

I want to summing all piece[1] in line
private async void search()
{
if (tbs.Text != null)
{
var files = await ApplicationData.Current.LocalFolder.GetFileAsync(logid.Text + ".txt");
var lines = await FileIO.ReadLinesAsync(files);
var pattern = tbs.Text;
foreach (string line in lines.Where(line => line.Contains(pattern)))
{
}
}
}
each line are something like this
income 10000
income 20000
I want to sum all the second piece (piece[1])
how to do this?
Assuming you have list like below, you can get the sum as:
List<string> list = new List<string>() { "income 10000", "income 20000", "income 30000" };
var sum = list.Sum(r => int.Parse(r.Split(' ')[1]));
The above assumes that you will have atleast 2 elements in the splitted array and its item on index 1 is of type integer. For the above you will get the result 60000
If you want to use int.TryParse then:
var sum = list.Sum(r => { int i;
return int.TryParse(r.Split(' ')[1], out i) ? i : 0; });
You can use string.Split method to do that, using the space character for separator. It will return an array of string, the amount will be the second element.
Then you convert the string value to int with int.TryParse to compute the sum.
private async void search()
{
if (tbs.Text != null)
{
var files = await ApplicationData.Current.LocalFolder.GetFileAsync(logid.Text + ".txt");
var lines = await FileIO.ReadLinesAsync(files);
var pattern = tbs.Text;
var sum = 0;
foreach (string line in lines)
{
var elements = line.Split(' ');
int value;
if (int.TryParse(elements[1], out value))
{
sum += value;
}
}
}
}

How do I produce a full set of combinations with string manipulation?

I have a small project where I have an input sentence where it is possible for the user to specify variations:
The {small|big} car is {red|blue}
Above is a sample sentence i want to split into 4 sentences, like this:
The small car is red
The big car is red
The small car is blue
The big car is blue
I can't seem to wrap my mind around the problem. Maybe someone can helt me pls.
Edit
Here is my initial code
Regex regex = new Regex("{(.*?)}", RegexOptions.Singleline);
MatchCollection collection = regex.Matches(richTextBox1.Text);
string data = richTextBox1.Text;
//build amount of variations
foreach (Match match in collection)
{
string[] alternatives = match.Value.Split(new char[] { '|', '{', '}' }, StringSplitOptions.RemoveEmptyEntries);
foreach (string alternative in alternatives)
{
//here i get problems
}
}
It sounds like you need a dynamic cartesian function for this. Eric Lippert's blog post written in response to Generating all Possible Combinations.
Firstly, we need to parse the input string:
Regex ex = new Regex(#"(?<=\{)(?<words>\w+(\|\w+)*)(?=\})");
var sentence = "The {small|big} car is {red|blue}";
then the input string should be modified to be used in string.Format-like functions:
int matchCount = 0;
var pattern = ex.Replace(sentence, me =>
{
return (matchCount++).ToString();
});
// pattern now contains "The {0} car is {1}"
then we need to find all the matches and to apply Eric's excellent CartesianProduct extension method:
var set = ex.Matches(sentence)
.Cast<Match>()
.Select(m =>
m.Groups["words"].Value
.Split('|')
).CartesianProduct();
foreach (var item in set)
{
Console.WriteLine(pattern, item.ToArray());
}
this will produce:
The small car is red
The small car is blue
The big car is red
The big car is blue
and, finally, the CartesianProduct method (taken from here):
static IEnumerable<IEnumerable<T>> CartesianProduct<T>(
this IEnumerable<IEnumerable<T>> sequences)
{
IEnumerable<IEnumerable<T>> emptyProduct = new[] { Enumerable.Empty<T>() };
return sequences.Aggregate(
emptyProduct,
(accumulator, sequence) =>
from accseq in accumulator
from item in sequence
select accseq.Concat(new[] {item}));
}
private void ExpandString( List<string> result, string text )
{
var start = text.IndexOf('{');
var end = text.IndexOf('}');
if (start >= 0 && end > start)
{
var head = text.Substring(0, start);
var list = text.Substring(start + 1, end - start - 1).Split('|');
var tail = text.Substring(end + 1);
foreach (var item in list)
ExpandString(result, head + item + tail);
}
else
result.Add(text);
}
Use like:
var result = new List<string>();
ExpandString(result, "The {small|big} car is {red|blue}");
If you don't know the number of variations, recursion is your friend:
static public IEnumerable<string> permute(string template)
{
List<string> options;
string before;
string after;
if (FindFirstOptionList(template, out options, out before, out after))
{
foreach (string option in options)
{
foreach (string permutation in permute(before + option + after))
{
yield return permutation;
}
}
}
else
{
yield return template;
}
}
static public bool FindFirstOptionList(string template, out List<string> options, out string before, out string after)
{
before = string.Empty;
after = string.Empty;
options = new List<string>(0);
if (template.IndexOf('{') == -1)
{
return false;
}
before = template.Substring(0, template.IndexOf('{'));
template = template.Substring(template.IndexOf('{') + 1);
if (template.IndexOf('}') == -1)
{
return false;
}
after = template.Substring(template.IndexOf('}') + 1);
options = template.Substring(0, template.IndexOf('}')).Split('|').ToList();
return true;
}
use is similar to danbystrom's solution, except this one returns an IEnumerable instead of manipulating one of the calling parameters. Beware syntax errors, etc
static void main()
{
foreach(string permutation in permute("The {small|big} car is {red|blue}"))
{
Console.WriteLine(permutation);
}
}
I would propose to split the input text into an ordered list of static and dynamic parts. Each dynamic part itself contains a list that stores its values and an index that represents the currently selected value. This index is intially set to zero.
To print out all possible combinations you at first have to implement a method that prints the complete list using the currently set indices of the dynamic parts. For the first call all indices will be set to zero.
Now you can increment the index of the first dynamic part and print the complete list. This will give you the first variation. Repeat this until you printed all possible values of the remaining dynamic parts.
Consider nesting iterative loops. Something like...
foreach(string s in someStringSet)
{
foreach(string t in someOtherStringSet)
{
// do something with s and t
}
}
Perhaps you are looking for this:
Edited version
static void Main(string[] args)
{
var thisstring = "The {Small|Big} car is {Red|Blue}";
string FirstString = thisstring.Substring(thisstring.IndexOf("{"), (thisstring.IndexOf("}") - thisstring.IndexOf("{")) + 1);
string[] FirstPossibility = FirstString.Replace("{", "").Replace("}", "").Split('|');
thisstring = thisstring.Replace(FirstString, "[0]");
string SecondString = thisstring.Substring(thisstring.IndexOf("{"), (thisstring.IndexOf("}") - thisstring.IndexOf("{")) + 1);
string[] SecondPosibility = SecondString.Replace("{", "").Replace("}", "").Split('|');
thisstring = thisstring.Replace(SecondString, "{1}").Replace("[0]", "{0}");
foreach (string tempFirst in FirstPossibility)
{
foreach (string tempSecond in SecondPosibility)
{
Console.WriteLine(string.Format(thisstring, tempFirst, tempSecond));
}
}
Console.Read();
}
Something like this should work:
private void Do()
{
string str = "The {small|big} car is {red|blue}";
Regex regex = new Regex("{(.*?)}", RegexOptions.Singleline);
int i = 0;
var strWithPlaceHolders = regex.Replace(str, m => "{" + (i++).ToString() + "}");
var collection = regex.Matches(str);
var alternatives = collection.OfType<Match>().Select(m => m.Value.Split(new char[] { '|', '{', '}' }, StringSplitOptions.RemoveEmptyEntries));
var replacers = GetReplacers(alternatives);
var combinations = new List<string>();
foreach (var replacer in replacers)
{
combinations.Add(string.Format(strWithPlaceHolders, replacer));
}
}
private IEnumerable<object[]> GetReplacers(IEnumerable<string[]> alternatives)
{
return GetAllPossibilities(0, alternatives.ToList());
}
private IEnumerable<object[]> GetAllPossibilities(int level, List<string[]> list)
{
if (level == list.Count - 1)
{
foreach (var elem in list[level])
yield return new[] { elem };
}
else
{
foreach (var elem in list[level])
{
var thisElemAsArray = new object[] { elem };
foreach (var subPossibilities in GetAllPossibilities(level + 1, list))
yield return thisElemAsArray.Concat(subPossibilities).ToArray();
}
}
yield break;
}
string color = SomeMethodToGetColor();
string size = SomeMethodToGetSize();
string sentence = string.Format("The {0} car is {1}", size, color);

Categories

Resources