Lire Csv en utilisant LINQ

J'ai un fichier csv comme ceci

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

Je veux imprimer la somme et la moyenne de chaque ligne et de sauter la première colonne. Comment faire dans LINQ en utilisant Lambda

22
demandé sur Joel 2011-02-25 14:21:45

8 réponses

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()
            };

Si vous lisez des fichiers volumineux et que l'utilisation de la mémoire est préoccupante, ce qui suit fonctionnera mieux en utilisant. 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()
            };

Dans les deux cas, la variable stuff contient un énumérable qui ne sera pas réellement exécuté jusqu'à ce que vous commenciez à le lire (par exemple dans une boucle foreach).

37
répondu Bennor McCarthy 2011-02-25 12:25:20
        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()));
        }
7
répondu Duncan Watts 2011-02-25 11:29:43

Essayez d'utiliser cette vieille mais toujours de bonne bibliothèque: FileHelpers Library

C'est très facile à utiliser:

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

Alors faites simplement:

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);
}
6
répondu digEmAll 2011-02-25 11:42:02
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]
  };
4
répondu MUG4N 2011-02-25 11:26:59

Je viens de découvrir la bibliothèque LinqToCsv, elle fait toutes les choses d'analyse et ensuite vous pouvez interroger des objets comme des collections et elle prend en charge la lecture différée:

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

1
répondu 0lukasz0 2012-11-21 17:46:58

Salut vous cherchez quelque chose comme ça

  var rows = new List<string> {"A, 22, 23, 12", "B, 32, 4, 33", "C, 34, 3 ,33"};
     foreach (var row in rows) {
            var sum = row.Split(',').Skip(1).Sum(x => Convert.ToInt32(x));
            var avg = row.Split(',').Skip(1).Average(x => Convert.ToInt32(x));
     }
0
répondu nhu 2011-02-25 11:29:34

Quelque chose comme ça peut-être:

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);
}

En général, je ne suggère pas de faire quelque chose comme ça. Vous devez utiliser un lecteur CSV complet pour analyser le fichier CSV et vous devez inclure la gestion des erreurs.

0
répondu Daniel Hilgarth 2011-02-25 11:31:58
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);

L'aporoach de streaming vous permettra de gérer les fichiers laregr parce que vous n'auriez pas besoin de les charger dans memeory en premier. Ne pas avoir VS ici, n'ont pas vérifié la syntaxe, pourraient ne pas compiler tel quel.

Cordialement GJ

Merde, beaucoup de réponses déjà, besoin de taper plus vite!

0
répondu gjvdkamp 2011-02-25 11:41:22