2012-04-27 7 views
0

ファイルをグローバル配列に読み込み、配列をループし、各文字列を対応する量で識別し、自身のグループで合計を見つけようとしています。それらのグループをそれぞれ独自の番号で分割します。2D配列を分割する最も効率的な方法は?

私が読んでいるテキストファイル:彼らは意志どの順番を知らない、コンマで行を分割し、数字はその特定の名前に対応させるための最も簡単な方法だろう何

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

これを行うには、より良い方法が必要なように感じます。

これまでにありがとうございました!私は、この問題が解決されていない唯一の理由は、私のコミュニケーションスキルの欠如であると確信しています。

答えて

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]; 
} 
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行はより明確にするために、私は任意のXML構文解析コードを追加したくなかったので、私はそのようにそれを分割しますが、一つに凝縮されるだろう。

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

編集あなたの最後の編集に応じて:

それはそれはまだありません対応する量だし、その後

独自のグループで合計を見つけるために、各文字列を識別達成したいことを明確にしてください。サンプルデータの望ましい結果が得られているはずです。私は金額が数字であり、グループが名前グループであると仮定します。

だから-group Name50+40+60=150DifferentName = 50AnotherName = 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]))); 

と第二のように和:

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

最初アプローチ:

だから私はあなたがそれぞれの番号に属している名前をしたいと仮定し

「の数字は、その特定の名前に対応します」。

  1. ライン

    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()); 
    
    IEnumerable<String>
  2. その後、
  3. 各行がString[]
  4. これらにコンマで分割されたファイルから読み込まれによってグループ化されています。これがtrueの場合Dictionary<String, List<String>>は最良の選択であります一意の数字とその名前を取得するための2番目の要素(番号)
  5. 結果はDictionaryを作成するために使用され、(今)固有の数字はキーであり、名前はList<String>

あなたはdictionariesに精通していない場合は、通常のキーによってそれらにアクセスするので、あなたは数"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); 
+0

彼のデータを見るとどちらもユニークではありません。 –

+0

@YuriyFaktorovich:私の説明は間違いだった。 OPの要件は、「数字を特定の名前に対応させる」ことでした。だから私は彼がすべての数字の名前を欲しいと思った。だから私は数字でグループ化した。 –

+0

@YuriyFaktorovich:私の答えを編集しました。今はそれがうまくはっきりしています。 –

関連する問題