Read Csv using LINQ

前端 未结 9 2120
无人及你
无人及你 2020-12-01 04:55

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

相关标签:
9条回答
  • 2020-12-01 04:59
    using System.IO
    
    // turn file into IEnumerable (streaming works better for larger files)
    IEnumerable<Tuple<int, int, int>> GetTypedEnumerator(string FilePath){
      var File = File.OpenText(FilePath);
      while(!File.EndOfStream) 
          yield return new Tuple<int, int, int>(
              Int.Parse(File[1]), 
              Int.Parse(File[2], 
              Int.Parse(File[3])
          );
       File.Close();
    }
    
    // this lines would return the sum and avg for each line
    var tot = GetTypeEnumerator(@"C:\file.csv").Select(l=>l.Item1 + l.Item2 + l.Item3);
    var avg = GetTypeEnumerator(@"C:\file.csv").Select(l=> (l.Item1 + l.Item2 + l.Item3) / 3);
    

    The streaming aporoach will let you handle laregr files because you wouldn;t need toload them into memeory first. Don't have VS here, haven't checked the syntax, might not compile as is.

    Regards GJ

    Damn, lot of answers already, need to type faster!

    0 讨论(0)
  • 2020-12-01 05:05

    Something like this maybe:

    var csv = @"A, 22, 23, 12
    B, 32, 4, 33
    C, 34, 3 ,33";
    
    var lines =
        csv.Split('\n').Select(x => x.Split(',').Skip(1).Select(n => int.Parse(n))).Select(x => new {Sum = x.Sum(), Average = x.Average()});
    foreach (var line in lines)
    {
        Console.WriteLine("Sum: " + line.Sum);
        Console.WriteLine("Average: " + line.Average);
    }
    

    In general, I don't suggest to do something like this. You should use a full blown CSV reader to parse the CSV file and you should include error handling.

    0 讨论(0)
  • 2020-12-01 05:08
    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]
      };
    
    0 讨论(0)
  • 2020-12-01 05:10
            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()));
            }
    
    0 讨论(0)
  • 2020-12-01 05:10

    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);
    }
    
    0 讨论(0)
  • 2020-12-01 05:12

    Actually for most cases you should avoid splitting based on ',' only because you could have coma in string.

    I give you a better generic solution using Regex and easy to use:

    var stuff = File.ReadAllLines(csvFilePath)
        .Skip(1) // For header
        .Select(s => Regex.Match(s, @"^(.*?),(.*?),(.*?),(.*?),(.*?)$"))
        .Select(data => new 
        {
            Foo = data.Groups[1].Value,
            Bar = data.Groups[2].Value,
            One = data.Groups[3].Value,
            Two = data.Groups[4].Value,
        });
    

    And you can find more details here https://stackoverflow.com/a/18147076/196526

    0 讨论(0)
提交回复
热议问题