чтение из текстового файла в неровный массив
-
21-08-2019 - |
Вопрос
Я нашел этот вопрос в старом вопросе на вашем сайте, поэтому подумал, что смогу это сделать, но думаю, что ошибся :-)
старый пост был здесь
Я новичок в работе с зубчатыми массивами, поэтому сделал следующий код
StreamReader rows = new StreamReader("c:\\practice.txt");
string line;
int i;
i=1;
while ((line = rows.ReadLine()) != null)
{
String[][]rows = new String [i][]; ;
rows = rows.ReadLine();
String[][] rows = new string[S.Length][];
i++;
}
for (int i; i < S.Length; i++)
{
row[i] = S[I].Split(',');
}
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;
}
}
Я знаю, что совершил серьезные ошибки, но на востоке я попробовал, может ли кто-нибудь помочь мне сделать это рабочим кодом?
Решение
Вы видимо перечитываете строки, а может быть перепутали строки и ячейки - особенно выглядит вот этот бит Действительно странный:
while ((line = rows.ReadLine()) != null)
{
String[][]rows = new String [i][]; ;
rows = rows.ReadLine();
String[][] rows = new string[S.Length][];
i++;
}
то естьповторное объявление строк, два вызова ReadLine
за петлю и т. д.Я подозреваю, что ты имеешь в виду string.Split
?В любом случае, либо используйте File.ReadAllLines
, или посмотрите на некоторые варианты, представленные вчера.Если вы отчаянно хотите использовать массивы, ядро может выглядеть примерно так:
using System;
using System.IO;
static class Program
{
static void Main()
{
string[] lines = File.ReadAllLines("foo.txt");
string[][] grid = new string[lines.Length][];
for (int i = 0; i < lines.Length; i++)
{
grid[i] = lines[i].Split(',');
}
int totalCount = 0, maleCount = 0, femaleCount = 0,
m1Total = 0, m2Total = 0, m3Total = 0,
m1MaleTotal = 0, m1FemaleTotal = 0;
foreach (string[] line in grid)
{
totalCount++;
int m1 = int.Parse(line[3]),
m2 = int.Parse(line[4]),
m3 = int.Parse(line[5]);
m1Total += m1;
m2Total += m2;
m3Total += m3;
switch (line[1].Trim())
{
case "male":
maleCount++;
m1MaleTotal += m1;
break;
case "female":
femaleCount++;
m1FemaleTotal += m1;
break;
}
}
Console.WriteLine("Rows: " + totalCount);
Console.WriteLine("Total m1: " + m1Total);
Console.WriteLine("Average m1: " + ((double)m1Total)/totalCount);
Console.WriteLine("Male Average m1: " + ((double)m1MaleTotal) / maleCount);
Console.WriteLine("Female Average m1: " + ((double)m1FemaleTotal) / femaleCount);
}
}
Опять же, я не могу не подчеркнуть, насколько вам следует делать это с помощью LINQ вместо ручного цикла...
Другие советы
Во-первых, убедитесь, что вы обертываете неуправляемые ресурсы, такие как потоки, в операторы using.
Лично мне нравится мой LineReader класс, который позволяет легко читать строки текста из файла (или чего-то еще).
Далее я бы избегайте использования массивов если только вам это действительно не нужно. List<T>
как правило, с ним намного приятнее работать.Теперь, если string.Split делает то, что вы хотите, вы можете легко получить List<String[]>
.В качестве альтернативы вы, вероятно, можете выполнить большую часть работы с помощью LINQ:
var query = from line in new LineReader("c:\\practice.txt")
let parts = line.Split(',')
select new { Gender=parts[2], Amount=int.Parse(parts[3]) };
Извлекать несколько агрегатов из одного потока данных в «обычном» LINQ сложно (именно поэтому мы с Марком Гравеллом разработали Нажмите LINQ).Однако вы можете использовать обычный оператор foreach:
int totalCounter = 0, totalSum = 0;
int maleCount = 0, maleSum = 0, femaleCount = 0, femaleSum = 0;
foreach (var row in query)
{
totalCounter++;
totalSum += row.Amount;
switch (row.Gender)
{
case "male":
maleCount++;
maleSum += Amount;
break;
case "female":
femaleCount++;
femaleSum += Amount;
break;
}
}
Если вы сгруппировали строки по полу, вы могли бы сделать это еще проще, особенно если вы знаете, что пол всегда «мужской» или «женский».