0

ファイルをグローバル配列に読み込み、配列をループして各文字列を対応する量に識別し、それぞれのグループで合計を見つけようとしています。そして、それらのグループをそれぞれ固有の番号で分割します。

私が読んでいるテキストファイル:

Name,50
Name,40
DifferentName,50
AnotherName,10
Name,60

行をコンマで分割し、番号を特定の名前に対応させ、順序がわからないようにする最も簡単な方法は何でしょうか。

これが私がこれまでに使用しているコードです。現在はファイルを開くダイアログですが、これを建設的なリファレンスとしてここに置いています。

        string strFileName;

    private void btnReadInFile_Click(object sender, EventArgs e)
    {
        //select the file
        OpenFileDialog ofdGetFile = new OpenFileDialog();
        if (ofdGetFile.ShowDialog() == DialogResult.Cancel)
        {
            //cancel
            MessageBox.Show("User Canceled");
            return;
        }
        else
        {
            //open the file
            StreamReader myStreamReader;
            strFileName = ofdGetFile.FileName;
            FileStream input = new FileStream(strFileName, FileMode.Open, FileAccess.Read);
            myStreamReader = new StreamReader(input);
            // other
            MessageBox.Show("Reading Complete", "Done!", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }
    }

    private void btnShowGrade_Click(object sender, EventArgs e)
    {
        if (strFileName != null)
        {
            String[][] nameSums = System.IO.File.ReadLines(strFileName)
           .Select(l => l.Split(','))                // split the line
           .GroupBy(arr => arr[0])                   // group by name
           .Select(grp => new String[]{
            grp.Key,
            grp.Sum(arr => int.Parse(arr[1])).ToString()})
           .ToArray();

        }
        else
        {
            MessageBox.Show("You need to read in a file first.");
        }
    }
}

これを行うにはもっと良い方法が必要だと思います。

これまでのご協力ありがとうございました!この問題が解決されなかった唯一の理由は、コミュニケーション能力の欠如だと確信しています。

4

4 に答える 4

1

最後の編集に従って編集します。

各文字列を対応する量に識別し、それぞれのグループで合計を見つけます

何を達成したいのかはまだはっきりしていません。サンプルデータの望ましい結果を提供する必要があります。金額は数、グループは名前グループだと思います。

したがって、Name-groupの場合、それは50+40+60=150DifferentName=50およびAnotherName= 10

これにより、一意の名前とそれに応じた量の辞書が作成されます。

Dictionary<String, int> nameSums = 
      System.IO.File.ReadLines(path)  // read lines from file
     .Select(l => l.Split(','))       // split the line
     .GroupBy(arr => arr[0])          // group by name
     .ToDictionary(grp =>  grp.Key, grp => grp.Sum(arr => int.Parse(arr[1])));

配列アプローチを主張する場合、以下は、名前を最初の要素、合計を2番目の要素としてジャグ配列(配列の配列)を作成して初期化します。

String[][] nameSums = System.IO.File.ReadLines(path)  // read lines from file
            .Select(l => l.Split(','))                // split the line
            .GroupBy(arr => arr[0])                   // group by name
            .Select(grp => new String[]{
                grp.Key,
                grp.Sum(arr => int.Parse(arr[1])).ToString()})
            .ToArray();

最初のアプローチ:

「番号を特定の名前に対応させる」

だから私はあなたがそれぞれの番号に属する名前が欲しいと思います。これが本当なら、aDictionary<String, List<String>>が最良の選択でしょう:

var numNames = System.IO.File.ReadLines(path)
    .Select(l => l.Split(','))
    .GroupBy(arr => arr[1])
    .ToDictionary(grp => grp.Key, grp => grp.Select(arr => arr[0]).ToList());
  1. 行はファイルから次のように読み取られますIEnumerable<String>
  2. 次に、各行がコンマで分割されてString[]
  3. これらは2番目の要素(番号)でグループ化され、一意の番号とその名前を取得します
  4. 結果はを作成するために使用されますDictionary。(現在の)一意の番号はキーであり、名前は次のような値です。List<String>

辞書に慣れていない場合は、通常、キーを使用して辞書にアクセスします。したがって、番号のすべての名前を知りたい場合は、次のようにします"50"

List<String> names = numNames["50"];
foreach(String name in names)
    Console.Write("name={0}", name);

または、すべてを繰り返したい場合:

foreach(var numName in numNames)
    foreach(var name in numName.Value)
        Console.Write("number={0} name={1}", numName.Key, name);
于 2012-04-27T19:13:57.547 に答える
0

あなたのタスクはIOバウンドです。ほとんどの場合、コードを変更してもメリットはありません。まず、プロファイラーを使用してアプリケーションのボトルネックを見つける必要があります。

.Net 4、4.5、またはSilverlightを使用している場合は、ReadLinesメソッドを使用してください。行のコレクションを表すイテレータを返します。スニペット:

        List<KeyValuePair<string, double> values = new List<KeyValuePair<string, double>();
        var lines = File.ReadLines(myFile);
        foreach (var line in lines)
        {
            var data = line.Split(',');
            var x = data[0];
            var y = Double.Parse(data[1], CultureInfo.InvariantCulture);
            var pair = new KeyValuePair<string, double>(x, y);
            values .Add(pair);
        }
于 2012-04-27T18:49:31.470 に答える
0
myArray = File.ReadAllLines(myFileName).Select(l => l.Split(',')).ToArray();

これは、2次元配列ではなく、千鳥配列になることに注意してください。2次元のものを作成するには、次のように使用できます。

lines = File.ReadAllLines(myFileName).Select(l => l.Split(',')).ToArray();
myArray = new string[lines.Count(), 2];
for(int i = 0; i < lines.Length; i++)
{
    myArray[i, 0] = lines[i, 0];
    myArray[i, 1] = lines[i, 1];
}
于 2012-04-27T18:40:37.953 に答える
0

辞書を使ってみませんか?

それで、

Dictionary<string,int> namesAndAges = new Dictionary<string,int>();
String[] line = new String[2];
while(there's still xml to read)
    {
        aLineOfXml = blah; //read a line of xml however you were gonna do it 
        line = aLineOfXml.Split(',');
        namesAndAges.Add(line[0],line[1]);
    }

whileループの最初の2行は、1つにまとめたほうがよいでしょうが、わかりやすくするために、またxml解析コードを追加したくないので、そのように分割しました。

于 2012-04-27T18:47:10.580 に答える