чтение из текстового файла в зубчатый массив

Я нашел этот вопрос в старом вопросе на вашем сайте, поэтому я думал, что смогу это сделать, но думаю, что ошибся :-)

старый пост был здесь

Я новичок в зубчатом массиве, поэтому сделал следующий код

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

Я знаю, что делал серьезные ошибки, но на востоке я пытался, может ли кто-нибудь помочь мне сделать это рабочим кодом?


person Community    schedule 12.12.2008    source источник
comment
Вряд ли старый - это было вчера, а сегодня все еще обновляется...   -  person Marc Gravell    schedule 12.12.2008
comment
Меня не убеждает не-домашняя работа... в том же классе, что и сюзана или что-то в этом роде?   -  person Marc Gravell    schedule 12.12.2008


Ответы (2)


Вы, кажется, дважды читаете строки или, возможно, вы перепутали строки и ячейки - в частности, этот фрагмент выглядит действительно странно:

        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 вместо ручного цикла...

person Marc Gravell    schedule 12.12.2008
comment
вчерашние варианты настолько заранее, что я не могу этого сделать, но вы можете показать мне, как это исправить - person ; 12.12.2008
comment
но что, если я хочу посчитать m2 и m3 - person ; 12.12.2008
comment
Спасибо, Марк, ты лучший из лучших - person ; 12.12.2008

Во-первых, убедитесь, что вы заключаете неуправляемые ресурсы, такие как потоки, в инструкции 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;
    }
}

Если вы сгруппировали строки по полу, вы могли бы сделать это еще проще, особенно если вы знаете, что пол всегда «мужской» или «женский».

person Jon Skeet    schedule 12.12.2008
comment
отлично, но все еще могу сделать это с помощью массивов - person ; 12.12.2008
comment
Вчера я получил пример PushLINQ ;-p - person Marc Gravell; 12.12.2008
comment
Брэндон: Если вам нужен массив, просто вызовите ToArray() - person Jon Skeet; 12.12.2008