Using delimiters to separate string into variables - c#

I have a list of string where each list item contains 6 values. Each value is separated by a comma. I want to use Split(',') to separate each value then assign each one to a variable
Do I have to use an array to create new variables, or is there a way to separate each value into existing variables?
Currently the code I have to do this is nothing but
foreach (String Item in ItemList)
{
string id="";
string slip = "";
string qty = "";
string itemEntered = "";
string UOM = "";
string desc = "";
string[] vars = Item.Split(',');
}

You just need to extract the split values by index:
string[] vars = line.Split(',');
string id = vars[0];
string slip = vars[1];
string Qty = vars[2];
string Item = vars[3];
string UOM = vars[4];
string Desc = vars[5];

Consider to use an available CSV-Parser instead of doing this manually. However, if your data never contains the separator and it's strict, your approach is fine. You just have to take the strings at the correct indices:
List<Data> data = new List<Data>();
foreach (String line in ItemList)
{
string[] vars = line.Split(',');
if (vars.Length == 6)
{
int id;
if(!int.TryParse(vars[0], out id))
continue;
string slip = vars[1];
int qty;
if(!int.TryParse(vars[2], out qty))
continue;
string item = vars[3];
string uom = vars[4];
string desc = vars[5];
data.Add(new Data { ID = id, Slip = vars[1], Quantity = qty, Desc = desc, Item = item, UOM = uom });
}
}
I have also used a custom class:
public class Data
{
public int ID { get; set; }
public string Slip { get; set; }
public int Quantity { get; set; }
public string Item { get; set; }
public string UOM { get; set; }
public string Desc { get; set; }
}

Related

Join sub variables in a List

I have my variables class with constructor
public class Gdf2Lines
{
public string line { get; set; }
public int linenumber { get; set; }
public string columnNumber { get; set; }
public string columnName { get; set; }
public Gdf2Lines()
{
line = "";
linenumber = -1;
columnNumber = ""; // prefer to keep as the string read from the text source
columnName = "";
}
}
I have my class that creates of list of the above class and populates the variables within for each line from a file
class GDF2
{
Gdf2Lines Data = new Gdf2Lines();
List<Gdf2Lines> gdf2 = new List<Gdf2Lines>();
public GDF2(string[] arrFile)
{
int count = 0;
foreach (String line in arrFile)
{
Data.line = line;
Data.linenumber = count;
Data.columnNumber = GetColumnNumber(line);
Data.columnName = GetColumnName(line);
count++;
gdf2.Add(Data);
}
}
}
I know a "normal" list can be joined into a string by:
String.Join(Environment.Newline.ToString(), List);
But is there an equally easy way to join one of the (sub) variables within my list, such as
String.Join(",", gdf2.columnName);
Currently I am using a for loop.
Something like this should work:
String.Join(",", gdf2.Select(x => x.columnName));
This uses LINQ to extract a list of columnName values from the list of Gdf2Line.

Parsing txt file to List

I have a txt file that want to store into a array. I'm running into a problem parsing when I have additional items on single line, as the pipe(|) would indicate another item to be stored.
Inv # Date term qty description price Tax
3221409:2017/01/12:215|10:WD2002:2TB Hard Drive:121.66:N|20:KG240S:240GB SSD:125.10:N|20:KG120S:120GB SSD:78.75:N
I'm trying to first try to open the file and show each element to the console. getting index outside the bounds of the array. The file doesn't have headers I provided them for information.
//this object lets you read from a file.
StreamReader streamReader = null;
string lineData;
string[] lineElements;
if (File.Exists(path))
{
Console.WriteLine("Woohoo file found");
try
{
int invoice;
String invoicedate;
int term;
int qty;
string description;
Boolean tax;
streamReader = new StreamReader(path);
while (streamReader.Peek() > 0)
{
lineData = streamReader.ReadLine();
var parts = lineData.Split('|');
lineElements = parts.First().Split(':');
invoice = int.Parse(lineElements[0]);
invoicedate = (lineElements[1]);
term = int.Parse(lineElements[2]);
qty = int.Parse(lineElements[3]);
Console.WriteLine(invoice);
Console.WriteLine(invoicedate);
Console.WriteLine(term);
Console.WriteLine(qty);
}
First define a structure that can hold the informations
public class InventoryData
{
public string Inv { get; set; }
public DateTime Date { get; set; }
public string Term { get; set; }
public IList<InventoryArticle> Articles { get; set; }
}
public class InventoryArticle
{
public int Quantity { get; set; }
public string Whatever { get; set; }
public string Description { get; set; }
public decimal Price { get; set; }
public bool Tax { get; set; }
}
then two methods, that will parse a single line into the structure
static InventoryData ParseInventoryData( string data )
{
var parts = data.Split( '|' );
var headparts = parts.First().Split( ':' );
var result = new InventoryData
{
Inv = headparts[0],
Date = DateTime.ParseExact( headparts[1], "yyyy/MM/dd", System.Globalization.CultureInfo.InvariantCulture ),
Term = headparts[2],
Articles = parts.Skip( 1 ).Select( part => ParseInventoryArticle( part ) ).ToList(),
};
return result;
}
static InventoryArticle ParseInventoryArticle( string data )
{
var parts = data.Split( ':' );
var result = new InventoryArticle
{
Quantity = int.Parse( parts[0] ),
Whatever = parts[1],
Description = parts[2],
Price = decimal.Parse( parts[3], System.Globalization.CultureInfo.InvariantCulture ),
Tax = parts[4] == "Y",
};
return result;
}
and finally how to parse the content of a file
string[] content = {
"Inv # Date term qty description price Tax",
"3221409:2017/01/12:215|10:WD2002:2TB Hard Drive:121.66:N|20:KG240S:240GB SSD:125.10:N|20:KG120S:120GB SSD:78.75:N" };
var data = content
// skip the header row
.Skip( 1 )
// parse the content
.Select( row => ParseInventoryData( row ) )
.ToList();

Read from textfile and split each line into different strings

i have to read from a textfile which contains the following formatting
PRODUCTID PRODUCTNAME CUSTOMERID CUSTOMERNAME AMOUNT.
The textfile contains 11 line and for each one of them i must store each eg. productid into one string, and productname into one string.
I have tried like this which only stores the length of each line..
List<string> list = new List<string>();
using (var reader = new StreamReader(#"Budget.txt"))
{
string line;
while ((line = reader.ReadLine()) != null)
{
list.Add(line);
}
}
EDIT: Created a class which hold the data
Create a class that rapresent your file line, like this:
public class Procuct {
public string ProductId {get;set;}
public string ProductName {get;set;}
public string CustomerId {get;set;}
public string CustomerName {get;set;}
public string Amount{get;set;}
}
Then create a list of product to store them:
List<Procuct> list = new List<Procuct>();
using (var reader = new StreamReader(#"Budget.txt"))
{
string line;
while ((line = reader.ReadLine()) != null)
{
var temp = line.Split(" ");
list.Add(new Product{
ProductId = temp[0],
ProductName = temp[1],
CustomerId = temp[2],
CustomerName = temp[3],
Amount = temp[4]
});
}
}
Once are stored you can use LINQ to get the information that you want.
You have to work with TextFieldParser Class it is used to parse delimited text lignes as columns
using System;
using Microsoft.VisualBasic.FileIO;
class Program
{
static void Main()
{
using (TextFieldParser parser = new TextFieldParser("C:\\csv.txt"))
{
parser.Delimiters = new string[] { " " };
while (true)
{
string[] parts = parser.ReadFields();
if (parts == null)
{
break;
}
Console.WriteLine("{0} field(s)", parts.Length);
}
}
}
}
There is a useful examples in this Topic
You can use some code like below to get what you want
static void Main(String[] args) {
var allRecords = new List<Record>();
foreach (var line in File.ReadLines("Budget.txt")) {
allRecords.Add(new Record(line));
}
}
public class Record {
public string ProductId { get; private set; }
public string ProductName { get; private set; }
public string CustomerId { get; private set; }
public string CustomerName { get; private set; }
public decimal Amount { get; private set; }
public Record(string line) {
var items = line.Split();
ProductId = items[0];
ProductName = items[1];
CustomerId = items[2];
CustomerName = items[3];
Amount = Convert.ToDecimal(items[4]);
}
public override String ToString() {
return $"ProductId:{ProductId}, ProductName:{ProductName}, CustomerId:{CustomerId}, CustomerName:{CustomerName}, Amount:{Amount}";
}
}
As your question is not very clear, I assume that your file format is as demonstrated by the example below
10 Enchiladas 27 John Doe 15.00
11 HotDogs 27 John Doe 5.00
12 Burgers 29 Jane Doe 10.00
.
.
.
and so on

Bulk Insert : Collection was modified; enumeration operation may not execute

I'm using this code for saving data into database (my data comes from a text file that I extract fields in that file using Regex) :
var list = new List<IdiomExample>();
using (var db = new MyDbContext())
{
foreach (Match match in r.Matches(input))
{
string val = match.Groups[1].Value; // Idiom
string val2 = match.Groups[2].Value; // Meaning
string val3 = match.Groups[3].Value; // Desc
foreach (Capture c in match.Groups["my"].Captures)
{
list.Add(new IdiomExample{Item = c.Value});
}
db.Idioms.Add(new Idiom
{
Verb = val,
Meaning = val2,
Description = val3,
IdiomExamples = list
});
db.SaveChanges();
}
}
but when I run my code I get this exception :
Collection was modified; enumeration operation may not execute.
My models :
public class Idiom
{
public Int32 Id { get; set; }
public string Verb { get; set; }
public string Meaning { get; set; }
public string Description { get; set; }
public IList<IdiomExample> IdiomExamples { get; set; }
}
public class IdiomExample
{
public Int32 Id { get; set; }
public string Item { get; set; }
}
when I check my table's data two records just insertedو Whereas it should be 500 records in Idioms's Table and about 1000 records in IdiomExamples's Table. How can I solve my problem?
Thanks in advance.
give it a shot:
using (var db = new MyDbContext())
{
foreach (Match match in r.Matches(input))
{
var list = new List<IdiomExample>();
string val = match.Groups[1].Value; // Idiom
string val2 = match.Groups[2].Value; // Meaning
string val3 = match.Groups[3].Value; // Desc
foreach (Capture c in match.Groups["my"].Captures)
{
list.Add(new IdiomExample{Item = c.Value});
}
db.Idioms.Add(new Idiom
{
Verb = val,
Meaning = val2,
Description = val3,
IdiomExamples = list
});
}
db.SaveChanges();
}

taking data from a csv file, and putting it into an array

public class Earthquake
{
public double Magnitude { get; set; }
public string Location { get; set; }
public double Latitude { get; set; }
public double Longitude { get; set; }
public double depth { get; set; }
public DateTime date { get; set; }
public string EventID { get; set; }
public string URL { get; set; }
public Earthquake()
: this(string.Empty, string.Empty, string.Empty, string.Empty, string.Empty, string.Empty, string.Empty, string.Empty)
{ }
public Earthquake(string magna, string locate, string lat, string longi, string dept, string dat, string Event, string website)
{
Magnitude = Convert.ToDouble(magna);
Location = locate;
Latitude = Convert.ToDouble(lat);
Longitude = Convert.ToDouble(longi);
depth = Convert.ToDouble(dept);
date = Convert.ToDateTime(dat);
EventID = Event;
URL = website;
}
}
public void GetData()
{
string[] text = File.ReadAllLines(#"Earthquakes.csv");
Earthquake[] data = new Earthquake[1];
foreach (string line in text)
{
string[] myColumns = line.Split(',');
Earthquake[] earth = new Earthquake[myColumns[0], myColumns[1], myColumns[2], myColumns[3], myColumns[4], myColumns[5], myColumns[6], myColumns[7]];
data[i] = earth[i];
i++;
}
}
Ignore commented parts I have those under control. The problem I am having is getting the data from the csv file into the Earthquake Array. I am getting syntax errors, and I know why, it's because the data type isn't correct, but I honestly cannot figure out how to fix it.
Also if you notice I am trying to use bubble sort and since there is no definition for "compare" for double, what do I use instead?
If your reading from CSV file you probably have to remove white space from the split values.
Try adding .Trim() to your column variables
myColumns[0].Trim()
if your looking to sort yor array consider using System.Linq
eg:
var byMag = earthQuakes.OrderBy(e => e.Magnitude);
Looking at your code you posted, GetData() will not work.
Try returning a list or Enumerable
public IEnumerable<Earthquake> GetData(string filename)
{
string[] text = File.ReadAllLines(filename);
foreach (string line in text)
{
string[] myColumns = line.Split(',');
yield return new Earthquake(myColumns[0].Trim(), myColumns[1].Trim(), myColumns[2].Trim(), myColumns[3].Trim(), myColumns[4].Trim(), myColumns[5].Trim(), myColumns[6].Trim(), myColumns[7].Trim());
}
}
Usage:
var earthquakes = GetData(#"Earthquakes.csv");

Categories

Resources