拆分2D阵列最有效的方法?

时间:2012-04-27 18:38:25

标签: c# .net

我正在尝试将文件读入全局数组,遍历数组并将每个字符串标识为相应的数量,然后在自己的组中找到总和。并按照自己唯一的数字划分这些群体。

我正在阅读的文本文件:

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 个答案:

答案 0 :(得分:1)

编辑根据您的上一次修改:

  

将每个字符串标识为相应的数量,然后在各自的组中找到总和

目前还不清楚你想要达到的目标。您应该已提供样本数据的所需结果。我假设金额是数字,组是名称组。

因此对Name - 组来说,50+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();

第一次方法:

“使数字与其特定名称相对应”

所以我假设你想要属于每个数字的名字。如果这是真的,Dictionary<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>
  5. 如果您不熟悉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);
    

答案 1 :(得分: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];
}

答案 2 :(得分: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解析代码,我将它拆分为。

答案 3 :(得分: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);
        }