Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Read Csv using LINQ

Tags:

c#

linq

I am having a csv file like this

A, 22, 23, 12
B, 32, 4, 33
C, 34, 3 ,33

I want to print the sum and average of each row and skip the first column. How to do in LINQ using Lambda

like image 410
Joel Avatar asked Feb 25 '11 11:02

Joel


5 Answers

var stuff = from l in File.ReadAllLines(filename)
            let x = l.Split(new [] {',', ' '}, StringSplitOptions.RemoveEmptyEntries)
                     .Skip(1)
                     .Select(s => int.Parse(s))
            select new
            {
                Sum = x.Sum(),
                Average = x.Average()
            };

If you're reading big files and memory use is a concern, then the following will work better using .NET 4:

var stuff = from l in File.ReadLines(filename)
            let x = l.Split(new [] {',', ' '}, StringSplitOptions.RemoveEmptyEntries)
                     .Skip(1)
                     .Select(s => int.Parse(s))
            select new
            {
                Sum = x.Sum(),
                Average = x.Average()
            };

In both cases, the stuff variable contains an enumerable which won't actually be executed until you start reading from it (e.g. inside a foreach loop).

like image 128
Bennor McCarthy Avatar answered Oct 22 '22 08:10

Bennor McCarthy


        string csvFile = @"myfile.csv";
        string[] lines = File.ReadAllLines(csvFile);

        var values = lines.Select(l => new { FirstColumn = l.Split(',').First(), Values = l.Split(',').Skip(1).Select(v => int.Parse(v)) });
        foreach (var value in values)
        {
            Console.WriteLine(string.Format("Column '{0}', Sum: {1}, Average {2}", value.FirstColumn, value.Values.Sum(), value.Values.Average()));
        }
like image 35
Duncan Watts Avatar answered Oct 22 '22 10:10

Duncan Watts


Try to use this old but still good library: FileHelpers Library

It's very easy to use:

char delimiter = ',';
var dt = FileHelpers.CsvEngine.CsvToDataTable(fileName,delimiter);

then just do:

var rowStats = dt.AsEnumerable()
                 .Select(x => x.ItemArray.Select(y => Convert.ToInt32(y)))
                 .Select(x => new { avg = x.Average(), sum = x.Sum() });

foreach (var rowStat in rowStats)
{
    Console.WriteLine("Sum: {0}, Avg: {1}", rowStat.sum, rowStat.avg);
}
like image 7
digEmAll Avatar answered Oct 22 '22 09:10

digEmAll


string[] csvlines = File.ReadAllLines(@txtCSVFile.Text);

var query = from csvline in csvlines
  let data = csvline.Split(',')
  select new
  {
   ID = data[0],
   FirstNumber = data[1],
   SecondNumber = data[2],
   ThirdNumber = data[3]
  };
like image 5
MUG4N Avatar answered Oct 22 '22 08:10

MUG4N


I just have discovered LinqToCsv library, it do all the parsing stuff and then you can query objects like collections and it supports deferred reading:

http://www.codeproject.com/Articles/25133/LINQ-to-CSV-library

like image 4
0lukasz0 Avatar answered Oct 22 '22 09:10

0lukasz0