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