I'm looking for a way to pass information from a text file into a constructor so that I can create an array of that constructor object with each object in the array holding information from the rows of the text file.
The constructor is formatted as follows:
public Member(string name, int number, decimal rate, double hours)
While the text file is formatted as such:
Eric Wallace, 352456, 15.88, 32.20
Clara Kell, 233424, 35.88, 18.76
Darren Price, 656795, 27.82, 20.25
etc...
and each Member will go into an array.
In the end, what I need is for each row to be split up and passed to the constructor in a way where each row becomes its own member in an array so that they can be output one after another in a loop or called individually as rows.
CodePudding user response:
My approach would begin with making an interface that all my "buildable" data types will implement. I want my data models deciding how they are built from a string:
public interface IBuildableFromString
{
public IBuildableFromString Build(string str, string seperator = ",");
}
Then make Member
implement it like so:
public class Member : IBuildableFromString
{
public string Name { get; set; }
public int Number { get; set; }
public decimal Rate { get; set; }
public double Hours { get; set; }
public Member() { }
public Member(string name, int number, decimal rate, double hours)
{
Name = name;
Number = number;
Rate = rate;
Hours = hours;
}
public IBuildableFromString Build(string str, string seperator = ",")
{
try
{
string[] parts = str.Split(seperator);
return new Member(parts[0], int.Parse(parts[1]),
decimal.Parse(parts[2]), double.Parse(parts[3]));
}
catch
{
return null;
}
}
}
Then the method to read the file and build the object data:
public static T[] BuildData<T>(string filePath) where T :
IBuildableFromString, new()
{
List<T> dataObjects = new List<T>();
string[] lines = File.ReadAllLines(filePath);
foreach (string line in lines)
{
if (!String.IsNullOrEmpty(line))
{
var newMember = new T().Build(line);
if (newMember != null)
dataObjects.Add((T)newMember);
}
}
return dataObjects.ToArray();
}
Lastly, call the function above like so:
static void Main(string[] args)
{
var data = BuildData<Member>(@"path_to_your_file.txt");
}
It probably needs more error checking, but this was the most extensible way I could think of doing it. Cheers!
CodePudding user response:
As long as your file is well-formed, then this would work:
Member[] members =
File
.ReadLines(@"mytextfile.txt")
.Select(x => x.Split(',').Select(y => y.Trim()).ToArray())
.Select(x => new Member(x[0], int.Parse(x[1]), decimal.Parse(x[2]), double.Parse(x[3])))
.ToArray();
CodePudding user response:
I will use StreamReader
to read the txt file, then use replace
to eliminate spaces, and then use split
to split the data.
Make Member implement it like so:
public class Member {
public string Name { get; set; }
public int Number { get; set; }
public decimal Rate { get; set; }
public double Hours { get; set; }
public Member(string name, int number, decimal rate, double hours) {
Name = name;
Number = number;
Rate = rate;
Hours = hours;
}
}
Call the data like this:
foreach (var item in members) {
Console.WriteLine($"{ item.Name} { item.Number} { item.Rate} { item.Hours}");
}
Total code:
using System;
using System.Collections.Generic;
using System.IO;
namespace ConsoleApp2 {
class Program {
static void Main(string[] args) {
List<Member> members = new List<Member>();
try {
// Create an instance of StreamReader to read from a file.
// The using statement also closes the StreamReader.
using (StreamReader sr = new StreamReader(@"C:\demo\de.txt")) {
string line;
// Read and display lines from the file until the end of
// the file is reached.
while ((line = sr.ReadLine()) != null) {
line = line.Replace(" ", "");
string[] tmp = line.Split(',');
string name = tmp[0];
int number = Convert.ToInt32(tmp[1]);
decimal rate = Convert.ToDecimal(tmp[2]);
double hours = Convert.ToDouble(tmp[3]);
members.Add(new Member(name, number, rate, hours));
}
}
} catch (Exception e) {
// Let the user know what went wrong.
Console.WriteLine("The file could not be read:");
Console.WriteLine(e.Message);
}
foreach (var item in members) {
Console.WriteLine($"{ item.Name} { item.Number} { item.Rate} { item.Hours}");
}
Console.ReadLine();
}
public class Member {
public string Name { get; set; }
public int Number { get; set; }
public decimal Rate { get; set; }
public double Hours { get; set; }
public Member(string name, int number, decimal rate, double hours) {
Name = name;
Number = number;
Rate = rate;
Hours = hours;
}
}
}
}
If you have questions, please add a comment.