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=150, DifferentName=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();

一种方法:

“使数字与它们的具体名称相对应”

所以我假设你想要属于每个数字的名称。如果这是真的 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. 这些按第二个元素(数字)分组以获得唯一的数字及其名称
  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();

请注意,这将是一个交错数组,而不是二维数组。要创建一个二维的,您可以使用

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 循环中的前两行最好压缩为一行,但为了清楚起见,因为我不想添加任何 xml 解析代码,所以我将其拆分为这样。

于 2012-04-27T18:47:10.580 回答