redcell98
redcell98

Reputation: 13

Sort text file data into an array

I'm working on a homework problem for my computer science class. A cities census data is on a text file holding records for its citizens. Each line will have four fields(age, gender, marital status, and district) of different data types separated by a comma. For example, 22, F, M, 1.

How should I approach this? My thoughts are that I should use two 1D arrays, one for age and one for district. I need to be able to later count how many people are in each district, and how many people are in different age groups for the whole city.

How do I read each line and get the info I want into each array?

edit** This is what I've managed to do so far. I'm trying to separate my data from fields into four different arrays. This is where I'm stuck.

        FileStream fStream = new FileStream("test.txt", FileMode.Open, FileAccess.Read);
        StreamReader inFile = new StreamReader(fStream);

        string inputRecord = "";
        string[] fields;
        int[] ageData = new int[1000];
        string[] genderData = new string[1000];
        string[] maritalData = new string[1000];
        int[] districtData = new int[1000];



        inputRecord = inFile.ReadLine();
        while (inputRecord != null)
        {
            fields = inputRecord.Split(',');

            int i = 0;

            ageData[i] = int.Parse(fields[0]);
            genderData[i] = fields[1];
            maritalData[i] = fields[2];
            districtData[i] = int.Parse(fields[3]);
            i++;

            inputRecord = inFile.ReadLine();
         }

edit 2**

First question, I've decided to use the below code to find out how many citizens are in each district of the census data.

for (int x = 1; x <= 22; x++)
            for (int y = 0; y < districtData.Length; y++)
                if (districtData[y] == x)
                    countDist[x]++;

        for (int x = 1; x <= 22; x++)
            Console.WriteLine("District   " + x + "   has   " + countDist[x] + "   citizens");

In my .Writeline when x reaches two digits it throws off my columns. How could I line up my columns better?

Second question, I am not quite sure how to go about separating the values I have in ageData into age groups using an if statement.

Upvotes: 0

Views: 1289

Answers (3)

Eric J.
Eric J.

Reputation: 150108

It sounds like each of the four fields have something in common... they represent a person surveyed by the census. That's a good time to use a class along the lines of

public class Person
{
    public int Age { get; set; }
    public string Gender { get; set; }
    public string MaritalStatus { get; set; }
    public int District { get; set; }
}

Then, just read in all of the lines from the text file (if it's small, it's fine to use File.ReadAllLines()), and then create an instance of Person for each line in the file.

You can create a

List<Person> people;

to hold the Person instances that you parse from the text file.

Since the lines appear to be separated by commas, have a look at String.Split().

UPDATE

The attempt in your edit is pretty close. You keep creating a new i and initializing it to 0. Instead, initialize it outside your loop:

int i = 0;
while (inputRecord != null)
{
    fields = inputRecord.Split(',');

Also you may want to trim excess spaces of of your input. If the fields are separated with ", " rather than just "," you will have excess spaces in your fields.

        genderData[i] = fields[1].Trim();
        maritalData[i] = fields[2].Trim();

Upvotes: 2

denys-vega
denys-vega

Reputation: 3697

public static class PersonsManager
{
    public static PersonStatistics LoadFromFile(string filePath)
    {
        var statistics = new PersonStatistics();
        using (var reader = new StreamReader(filePath))
        {
            var separators = new[] { ',' };
            while (!reader.EndOfStream)
            {
                var line = reader.ReadLine();

                if (string.IsNullOrWhiteSpace(line))
                    continue; //--malformed line

                var lParts = line.Split(separators, StringSplitOptions.RemoveEmptyEntries);
                if (lParts.Length != 4)
                    continue; //--malformed line

                var person = new Person
                {
                    Age = int.Parse(lParts[0].Trim()),
                    Gender = lParts[1].Trim(),
                    MaritalStatus = lParts[2].Trim(),
                    District = int.Parse(lParts[3].Trim())
                };

                statistics.Persons.Add(person);
            }
        }

        return statistics;
    }
}

public class PersonStatistics
{
    public List<Person> Persons { get; private set; }

    public PersonStatistics()
    {
        Persons = new List<Person>();
    }

    public IEnumerable<Person> GetAllByGender(string gender)
    {
        return GetByPredicate(p => string.Equals(p.Gender, gender, StringComparison.InvariantCultureIgnoreCase));
    }

    //--NOTE: add defined queries as many as you need
    public IEnumerable<Person> GetByPredicate(Predicate<Person> predicate)
    {
        return Persons.Where(p => predicate(p)).ToArray();
    }
}

public class Person
{
    public int Age { get; set; }
    public string Gender { get; set; }
    public string MaritalStatus { get; set; }
    public int District { get; set; }
}

Usage:

var statistics = PersonsManager.LoadFromFile(@"d:\persons.txt");
var females = statistics.GetAllByGender("F");
foreach (var p in females)
{
    Console.WriteLine("{0} {1} {2} {3}", p.Age, p.Gender, p.MaritalStatus, p.District);
}

I hope it helps.

Upvotes: 0

Xela
Xela

Reputation: 2382

How about this?

List<string[]> o = File.ReadAllLines(@"C:\TestCases\test.txt").Select(x => x.Split(',')).OrderBy(y => y[0]).ToList();

Each person is a string array in the list. Each property is a index in the array eg: age is first. The above code reads all lines comma delimits them orders them by age and adds them to the list.

Upvotes: 0

Related Questions