Creating a multidimensional array from a string with delimiter - c#

I have an comma separated string like this:
string myString = "1,a,b,C1,,#2,d,e,C2,,#3,f,g,C3,,#4,h,i,C4,,#";
This is basically the data from an csv file where I am using reader to read from file.
In the above string ',' represents the data delimeter while '#' represents EOL of the file.
myString = myString.TrimEnd('#'); //Removing extra # in the end.
//Result of above 1,a,b,C1,,#2,d,e,C2,,#3,f,g,C3,,#4,h,i,C4,,
I want to convert the above into multidimentional array, loop through it reading value of each row data and create my own json.
So I started with the below code. This would result me with row and column count.
int rowCount = result.TrimEnd('#').Split('#').Count();
int colCount = result.TrimEnd('#').Split('#')[0].TrimEnd(',').Split(',').Length;
//Defining my object which I want to fill.
JObject myObject = new JObject();
Below I want to loop through row and column getting data value from each row and column
for (int row = o ; row <= rowCount; row++)
{
for (int col = 0; col <= colCount; col++)
{
//So here I want to do something like:
var rowValue = multiArray[row][col];
//After getting the row value below is the logic to add to my object
if(col == 0)
{
myObject.Add("first", rowValue);
}
else if(col == colCount)
{
myObject.Add("last", rowValue);
}
else
{
myObject.Add(col, rowValue);
}
}
}
So my question is how can I create the multidimentional array "multiArray" in my code.
Example of my json:
{
"first": 1
"1": a,
"2": b,
"last": C1
},
{
"first": 2
"1": c,
"2": d,
"last": C2
}

The following code creates and fills your multi-dimensional array, but there is a problem with your data. Because of the extra commas your json will not look like your sample json.
string myString = "1,a,b,C1,,#2,d,e,C2,,#3,f,g,C3,,#4,h,i,C4,,#".TrimEnd('#');
var rows = myString.Split('#');
var rowCount = rows.Length;
var columnCount = rows[0].Split(',').Length;
string[,] multiArray = new string[rowCount, columnCount];
for (int i = 0; i < rowCount; i ++)
{
var values = rows[i].Split(',');
for (int j = 0; j < columnCount && j < values.Length; j++)
{
multiArray[i,j] = values[j];
}
}
The results I get from this are that there is a 4x6 array with only 4 values in each row.

Related

Columns in Multidimensional Arrays c#

I have data in txt like this:
flea,0,0,1,0,0,0,0,0,0,1,0,0,6,0,0,0,6
frog,0,0,1,0,0,1,1,1,1,1,0,0,4,0,0,0,5
frog,0,0,1,0,0,1,1,1,1,1,1,0,4,0,0,0,5
I need to count the number of zeros in a chosen column, for example in the first column there are 3 zeros.
Here is my code so far:
//data patch
string[] tekst = File.ReadAllLines(#"C:\zoo.txt");
//full of array
string[] tablica = tekst;
for(int s=0;s<tablica.Length;s++)
{
Console.WriteLine(tablica[s]);
}
//----------------Show all of array---------------------------//
//----------------Giv a number of column-----------------////
Console.WriteLine("Podaj kolumne");
int a = Convert.ToInt32(Console.ReadLine());
//Console.WriteLine("Podaj wiersz");
//int b = Convert.ToInt32(Console.ReadLine());
int n = tablica.Length;
int m = tablica[a].Split(',').Length;
string[,] liczby = new string[n, m];
for (int j = 0; j < n; j++)
{
int suma = 0;
for (int i = 0; i < m; i++)
{
//somethink should be here
}
}
Any ideas for solving this?
try:
//data patch
string[] tekst = File.ReadAllLines(#"C:\zoo.txt");
//full of array - you allready have a string[], no need for a new one
//string[] tablica = tekst;
for(int s=0;s<tekst.Length;s++)
{
Console.WriteLine(tekst[s]);
}
//----------------Show all of array---------------------------//
//----------------Giv a number of column-----------------////
// try to use names with some meaning for variables, for example instead of "a" use "column" for the column
Console.WriteLine("Podaj kolumne");
int column = Convert.ToInt32(Console.ReadLine());
// your result for zeros in a given column
int suma = 0;
// for each line in your string[]
foreach ( string line in tekst )
{
// get the line separated by comas
string[] lineColumns = line.Split(',');
// check if that column is a zero, remember index is base 0
if ( lineColumns[column-1] == "0" )
suma++;
}
Console.WriteLine(suma);
EDIT: Just make sure to validate that the column they ask for, really exist in your array, AND if you do not consider the first column as the one with the name, adjust this part
lineColumns[column] // instead of lineColumns[column-1]

How to convert nested for loops with if condition to LINQ

I have a horrible method that extracts data from a DataTable and converts it to a desirable formatted DataTable. I'm sure there is a much nicer way to do this in LinQ but I'm not really experienced with it. I would appreciate if somebody could show me a nicer solution.
Heres the code
private static void ExtractImportLayoutFromExcelDt(DataTable importDt, DataTable dtExtracted, int languages)
{
// The number of Locale colums included in the excel file.
for (int x = 0; x < languages; x++)
{
// The total number of friendlynames-keys / language included in the excel.
for (int j = 0; j < dtExtracted.Rows.Count; j++)
{
var row = dtExtracted.Rows[j];
DataRow tempRow = importDt.NewRow();
// Filling in the 3 columns. (FriendlyName - LocaleID - Text)
for (int i = 0; i <= 2; i++)
{
if (i == 0)
{
tempRow[i] = row[i]; // Friendly names: This is always going to be column 1 [0].
}
else if (i == 1)
{
tempRow[i] = Regex.Match(dtExtracted.Columns[x + 1].ToString(), #"\d+").Value; // LocaleIDs: Getting rid of non numeric characters from this column.
}
else
{
tempRow[i] = row[x + 1];
}
}
importDt.Rows.Add(tempRow);
}
}
}
i would rewrite inner for loops
for (int x = 0; x < languages; x++)
foreach (DataRow row in dtExtracted.Rows)
importDt.Rows.Add
(
row[0],
Regex.Match(dtExtracted.Columns[x + 1].ToString(), #"\d+").Value; // LocaleIDs: Getting rid of non numeric characters from this column.
row[x + 1]
);
DataTable.Rows collection has overload of Add method, which accept an array of objects: Add
I am not quite sure if LINQ could be of any help here, but apart from rewriting the entire mapping logic I would at least split this method into two:
private static void ExtractImportLayoutFromExcelDt(DataTable importDt, DataTable dtExtracted, int languages)
{
// The number of Locale colums included in the excel file.
for (int x = 0; x < languages; x++)
{
// The total number of friendlynames-keys / language included in the excel.
for (int j = 0; j < dtExtracted.Rows.Count; j++)
{
AddRow(importDt, dtExtracted, dtExtracted.Rows[j], x+1);
}
}
}
private static void AddRow(DataTable table, DataTable dtExtracted, DataRow originalRow, int language)
{
var row = table.NewRow();
row[0] = originalRow[0];
row[1] = Regex.Match(dtExtracted.Columns[language].ToString(), #"\d+").Value;
row[2] = originalRow[language];
table.Rows.Add(row);
}
You can write something like this but in this case is more like abuse of Linq but if you do it for educational purposes ..The main power of LINQ is when you want to enumerate or filter for example collections not in cases like this.
public static void ExtractImportLayoutFromExcelDt(DataTable importDt, DataTable dtExtracted, int languages)
{
Enumerable.Range(0, languages)
.ToList().ForEach(x =>
{
Enumerable.Range(0, dtExtracted.Rows.Count)
.ToList().ForEach(j =>
{
var row = dtExtracted.Rows[j];
DataRow tempRow = importDt.NewRow();
AddRow(importDt, dtExtracted, x, row, tempRow);
});
});
}
private static void AddRow(DataTable importDt, DataTable dtExtracted, int x, DataRow row, DataRow tempRow)
{
for (int i = 0; i <= 2; i++)
{
if (i == 0)
{
tempRow[i] = row[i]; // Friendly names: This is always going to be column 1 [0].
}
else if (i == 1)
{
tempRow[i] = Regex.Match(dtExtracted.Columns[x + 1].ToString(), #"\d+").Value; // LocaleIDs: Getting rid of non numeric characters from this column.
}
else
{
tempRow[i] = row[x + 1];
}
}
importDt.Rows.Add(tempRow);
}

Checking the size of a list of arrays

I have a list of string arrays:
List<string[]> parsedRaw = new List<string[]>();
This list contains lines read in from a CSV, where parsedRaw[3][5] would be the fifth item read off the third line of the CSV.
I know that I can find the number of rows in the list with:
parsedRaw.Count
But, given a row, how can I find the number of elements in that row? I'm trying to implement a test before entering a loop to read from the list, in order to avoid an "Index was outside the bounds of the array" error, where the loop is:
for (k = 0; k < nBytes; k++)
{
TheseBytes[k] = (byte)parsedRaw[i][StartInt + k];
}
I'm encountering the error on a row in the CSV that has fewer elements than the others. Before entering this loop, I need to check whether parsedRaw[i] has at least "StartInt + nBytes" elements.
Thanks for any suggestions!
A row is just a string array string[], so you can find its size using the Length property of the array.
foreach (string[] row in parsedRaw) {
for (int i = 0 ; i != row.Length ; i++) {
// do something with row[i]
}
}
The number of elements in a given row is determined by
parsedRaw[theRowIndex].Length
To fix your for loop you need to constrain the StartInt + k value to be less than the minimum of nBytes and the row length
for (k = 0; (k < nBytes) && (k + StartInt < parsedRaw[i].Length); k++)
{
TheseBytes[k] = (byte)parsedRaw[i][StartInt + k];
}
Try
List<string[]> parsedRaw = new List<string[]>();
parsedRaw.Add(new string[] {"test1", "test2"});
parsedRaw.Add(new string[] { "test1", "test2", "test3" });
int totalSize = 0;
for (int i = 0; i < parsedRaw.Count(); i++)
{
int rowSize = 0;
for (int k = 0; k < parsedRaw[i].Count(); k++)
{
rowSize += parsedRaw[i][k].Length;
}
totalSize += rowSize;
}

insert datarow value at particular row

I want to insert datarow value in datatable particular row. Am having a datatable with values and then i want to overwrite the particular row value using c#.
my partial code id here:
for (int j = 0; j < DT.Rows.Count; j++)
{
row = DT2.NewRow();
row["Employee ID"] = Convert.ToString(DS.Rows[j]["fldempid"]);
row["Employee Name"] = Convert.ToString(DS.Rows[j]["fldempname"]);
string leavehstry = Convert.ToString(DS.Rows[j]["fldleavehistory"]);
string[] textarray1 = leavehstry.Split('-');
char[] delimiterChars1 = { ':' };
for (int i = 1; i <= textarray1.Length - 1; i++)
{
string[] words = textarray1[i - 1].Split(delimiterChars1);
string value = words[0].ToString();
string value1 = words[1].ToString();
row[value] = value1;
ivalue = i;
}
//DT2.Rows[j].Delete(); //I want to insert (or) overwrite the row value at j th position.
//DT2.Rows.Add(row);
//DT2.Rows[j].AcceptChanges();
}
please help me to insert it..
You can insert a DataRow in a DataTable at a specified index location by using the InsertAt method.
You might do this in place of your three commented out lines:
DT2.InsertAt(row, j);
If EmployerID is an unique value, then compare the DataColumn "EmployerID" value with EmployerID and Assign the datarow values as you want by using for loop.

Storing the records in csv file from datatable

I have datatable and I am displaying those values in the datagridview with the helping of code :
dataGridView1.ColumnCount = TableWithOnlyFixedColumns.Columns.Count;
dataGridView1.RowCount = TableWithOnlyFixedColumns.Rows.Count;
for (int i = 0; i < dataGridView1.RowCount; i++)
{
for (int j = 0; j < dataGridView1.ColumnCount; j++)
{
dataGridView1[j, i].Value = TableWithOnlyFixedColumns.Rows[i][j].ToString();
}
}
TableExtractedFromFile.Clear();
TableWithOnlyFixedColumns.Clear();
Now I want to save the records in the datatable in csv file.How can I do that ?
You could do this:
// we'll use these to check for rows with nulls
var columns = yourTable.Columns
.Cast<DataColumn>();
// say the column you want to sort by is called "Date"
var rows = yourTable.Select("", "Date ASC"); // or "Date DESC"
using (var writer = new StreamWriter(yourPath)) {
for (int i = 0; i < rows.Length; i++) {
DataRow row = rows[i];
// check for any null cells
if (columns.Any(column => row.IsNull(column)))
continue;
string[] textCells = row.ItemArray
.Select(cell => cell.ToString()) // may need to pick a text qualifier here
.ToArray();
// check for non-null but EMPTY cells
if (textCells.Any(text => string.IsNullOrEmpty(text)))
continue;
writer.WriteLine(string.Join(",", textCells));
}
}

Categories

Resources