Read text from a file and apply some operations to it

I have a problem with how to read text from a file and perform operations on it, for example

I have this text file which includes

// name - // sex --------- // birth // m1 // m2 // m3

fofo, male,    1986, 67, 68,  69
momo, male,    1986, 99, 98,  100
Habs, female,  1988, 99, 100, 87
toto, male,    1989, 67, 68,  69
lolo, female,  1990, 89, 80,  87
soso, female,  1988, 99, 100, 83

      

Now I know how to read line by line until I reach zero.

but this time I want to execute the average function later too to get the average of the first number of numbers m1

and then get the mean m1 for women only and men only

and some other operations that I cannot solve


I need help, I don't know how to get it what I mean is to read each line in a text file and put it on a string, then split the line (str.Split (',');) but how to get the m1 entry for each line I am really confused, should I use regex to get integers? should i use a 2d array? I'm completely lost, any ideas?

please if you can improve any ideas with sample code which would be great and kindness initiator from u.

and after i do i will send it to you guys to check.

{like a girl. I think I made the wrong decision to join the IT community :-(}

0


source to share


7 replies


Try something like this.



  var qry = from line in File.ReadAllLines(@"C:\Temp\Text.txt")
            let vals = line.Split(new char[] { ',' })
            select new
            {
              Name = vals[0].Trim(),
              Sex = vals[1].Trim(),
              Birth = vals[2].Trim(),
              m1 = Int32.Parse(vals[3]),
              m2 = Int32.Parse(vals[4]),
              m3 = Int32.Parse(vals[5])
            };

  double avg = qry.Average(a => a.m1);
  double GirlsAvg = qry.Where(a => a.Sex == "female").Average(a => a.m1);
  double BoysAvg = qry.Where(a => a.Sex == "male").Average(a => a.m1);

      

+5


source


I wrote a blog post for a while detailing the action of reading a CSV file and parsing its columns:

http://www.madprops.org/blog/back-to-basics-reading-a-csv-file/



I used the approach you mentioned (by splitting the string) and then applied the DateTime.TryParseExact () method and related methods to convert the individual values ​​to the types I need.

Hope the post helps!

+1


source


(note: this may seem like a tricky solution, but I am assuming the original data is large (many rows), so loading it into List<T>

might not be possible)

Reading a file would be nicely done with an iterator block ... if the data is large, you only want to process one line at a time, not a 2D array.

Actually it looks like it fits MiscUtil . A PushLINQ approach that can execute multiple aggregates at the same time on a data stream without buffering ...

Example below ...

Why is this useful?

Because it allows you to write multiple queries on the data source using standard LINQ syntax, but only read it once.

Example

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using MiscUtil.Linq;
using MiscUtil.Linq.Extensions;
static class Program
{

    static void Main()
    {
        // prepare a query that is capable of parsing
        // the input file into the expected format
        string path = "foo.txt";
        var qry = from line in ReadLines(path)
                  let arr = line.Split(',')
                  select new
                  {
                      Name = arr[0].Trim(),
                      Male = arr[1].Trim() == "male",
                      Birth = int.Parse(arr[2].Trim()),
                      M1 = int.Parse(arr[3].Trim())
                      // etc
                  };

        // get a "data producer" to start the query process
        var producer = CreateProducer(qry);

        // prepare the overall average
        var avg = producer.Average(row => row.M1);

        // prepare the gender averages
        var avgMale = producer.Where(row => row.Male)
                    .Average(row => row.M1);    
        var avgFemale = producer.Where(row => !row.Male)
                    .Average(row => row.M1);

        // run the query; until now *nothing has happened* - we haven't
        // even opened the file    
        producer.ProduceAndEnd(qry);

        // show the results
        Console.WriteLine(avg.Value);
        Console.WriteLine(avgMale.Value);
        Console.WriteLine(avgFemale.Value);
    }
    // helper method to get a DataProducer<T> from an IEnumerable<T>, for
    // use with the anonymous type
    static DataProducer<T> CreateProducer<T>(IEnumerable<T> data)
    {
        return new DataProducer<T>();
    }
    // this is just a lazy line-by-line file reader (iterator block)    
    static IEnumerable<string> ReadLines(string path)
    {
        using (var reader = File.OpenText(path))
        {
            string line;
            while ((line = reader.ReadLine()) != null)
            {
                yield return line;
            }
        }
    }

}

      

+1


source


Is there a reason not to create a data structure that stores file fields, string, boolean (for m / f), integer and 3 integers that you can put into a list that stores the values ​​and then iterate over to calculate different sums, averages, any other aggregate functions you would like.

+1


source


I recommend using the FileHelpers library. Example here: Quick Start

You can calculate the average in a foreach loop like on a page.

0


source


Susana, I apologize in advance, but I do not want to offend you. You have already said, "As a girl, you made the wrong decision to join THIS ..." and I have heard this before from my sisters talking all the time when I tried to help them choose their profession. But if you have conceptual difficulties following the answers above without just copying and pasting the code, I think you just validated part of your statement.

Having said that, there is more to IT than just writing code. In other words, coding may not be easy for you, but there are other areas in IT that you could surpass, including becoming a manager one day. I have had many managers who are not capable of doing this in any language, but they are good at managing people, projects and resources.

Trust me, it only gets harder from here. This is a very simple programming task. But if you realize this quickly enough, you can talk to your managers asking about incompatibilities in the company. QA can also be an alternative. Again, I just want to help and I'm sorry if you are offended. Good luck.

0


source


Repeat your repetition of "what if"; you just loop:

// rows is the jagged array of string1, string2 etc
int totalCounter = 0, totalSum = 0; // etc
foreach(string[] row in rows)
{
    int m1 = int.Parse(row[3]);
    totalCounter++;
    totalSum += m1;
    switch(row[2]) {
        case "male":
            maleCount++;
            maleSum += m1;
            break;
        case "female":
            femaleCount++;
            femaleSum += m1;
            break;
    }
}

      

etc .. However, while it works, you can do the same thing much more conveniently / expressively in C # 3.0 with LINQ, and this is what many of the existing answers try to show ... The point is, that Tim J's post already does all of this:

  • ReadAllLines: gets an array of strings per line
  • Split: gets an array of data in a string
  • "select new {...}": parses the data into something usable
  • Lines 3 "avg" show how to take averages over the filtered data

The only change I would make is that I added a bunch of ToArray () in there somewhere, so we only read the file once ...

0


source







All Articles