使用字典按月和年填充 DataGridView

Filling a DataGridView by Month and Year using Dictionary

我需要一些帮助。

我有一个 DataGridView (dgv),我正在用 txt 文件中的数据填充它。

dgv 是:

J | F | M | A | M | J | J | A | S | O | N | D
  |   |   |   |   |   |   |   |   |   |   |

在那个 txt 文件中,我通过以下方式有数千条记录:

id1_id2_date1_date2_data1_data2_data3_..._num1_num2_bool1_bool2_bool3

我正在使用 StreamReader 逐行阅读。每行变成一个对象Record b。然后我将 b.date.Month 转换为 switch 以按月拆分记录。我需要的记录信息是 num1。我用了 Dictionary<int, int> 来做到这一点。所以:

<1,x>
<2,x>
...
<12,x>

每本词典都有属于该月的所有记录,与年份无关。此处对这些记录使用 X。

J | F | M | A | M | J | J | A | S | O | N | D
x | x | x | x | x | x | x | x | x | x | x | x

但现在我需要这样做:

  Y   | J | F | M | A | M | J | J | A | S | O | N | D
2015  | x | x | x | x | x | x | x | x | x | x | x | x
2016  | x | x | x | x | x | x | x | x | x | x | x | x
2017  | x | x | x | x | x | x | x | x | x | x | x | x
2018  | x | x | x | x | x | x | x | x | x | x | x | x
2019  | x | x | x | x | x | x | x | x | x | x | x | x
...

但是我卡住了。我想不通。 我想过类似 Dictionary<int, Dictionary<int, int>> 的方法,但那行不通,因为年份是动态信息。

代码:

private void Form_Load(object sender, EventArgs e)
{
  FileStream fs;
  Dictionary<int, int> dataByMonth = new Dictionary<int, int>();
  Record b;

  try
  {
    if (File.Exists("data.txt"))
    {
      fs = new FileStream("data.txt", FileMode.Open, FileAccess.Read, FileShare.Read);
      using (StreamReader sr = new StreamReader(fs))
      {
        while (!sr.EndOfStream)
        {
          b = new Record(sr.ReadLine());

          // Get the month
          int month = b.date1.Month;
          
          // Thx to Steve for pointing out the unnecessary switch
          if (!dataByMonth.ContainsKey(month))
            dataByMonth.Add(m, b.num1);
          else
            dataByMonth[month] += b.num1;
        }
      }

      string str = string.Empty;
      foreach (KeyValuePair<int, int> x in dataByMonth)
      {
        str += x.Value.ToString() + "_";
      }

      string[] str1 = str.Split('_');
      dgv.Rows.Add(str1);
    }
  }
}

结果:

帮忙?

你的Recordclass长什么样?

我认为最简单的方法是修改 Record class 的构造函数,以便在 List<Record> 或类似的东西中翻译和存储你想要从每一行中获取的值那。然后你可以使用 LINQ 来查询你的列表和 groupby 月,对 num 等进行聚合

类似于:

public class Record
{
    public DateTime RecordDate {get;set;}
    public int RecordMonth {get;set;}
    public int RecordYear {get;set;}
    public int TheCount {get;set;}

  public Record(string lineIn)
  {
      var splitValues = lineIn.Split('_');
      int outNum;
      TheCount = int.TryParse(splitValues[7], out outNum)?outNum:0;
      var inDateString = splitValues[2];
      DateTime outDate;
      RecordDate = DateTime.TryParseExact(inDateString, "yyyy-MM-dd", CultureInfo.InvariantCulture, DateTimeStyles.None, out outDate)? outDate : DateTime.MinValue;
      RecordMonth = RecordDate.Month;
      RecordYear = RecordDate.Year;
  }
}

然后在您的流式阅读器中,更像是:

var theData = new List<Record>();
while (!sr.EndOfStream)
{
  theData.Add(new Record(sr.ReadLine());
}

现在您可以通过 LINQ 处理您的数据。使用groupby等

这是一个完整的示例(和 link 到 dot net fiddle: https://dotnetfiddle.net/AmuMiq

using System;
using System.Globalization;
using System.Collections.Generic;
using System.Linq;
                    
public class Program
{
    public static void Main()
    {
        var records = new List<Record>();
        
        //pattern = id1_id2_date1_date2_data1_data2_data3_..._num1_num2_bool1_bool2
        records.Add(new Record("abc_def_2020-03-01_2019-01-01_hello_hello_hello_51_100_true_false"));
        records.Add(new Record("abc_def_2020-03-02_2019-01-01_hello_hello_hello_62_100_true_false"));
        records.Add(new Record("abc_def_2020-03-03_2019-01-01_hello_hello_hello_73_100_true_false"));
        records.Add(new Record("abc_def_2020-03-04_2019-01-01_hello_hello_hello_34_100_true_false"));
        records.Add(new Record("abc_def_2020-03-05_2019-01-01_hello_hello_hello_25_100_true_false"));
        records.Add(new Record("abc_def_2020-04-01_2019-01-01_hello_hello_hello_56_100_true_false"));
        records.Add(new Record("abc_def_2020-04-02_2019-01-01_hello_hello_hello_67_100_true_false"));
        records.Add(new Record("abc_def_2020-04-03_2019-01-01_hello_hello_hello_78_100_true_false"));
        records.Add(new Record("abc_def_2020-04-04_2019-01-01_hello_hello_hello_39_100_true_false"));
        records.Add(new Record("abc_def_2020-04-05_2019-01-01_hello_hello_hello_20_100_true_false"));
        records.Add(new Record("abc_def_2020-05-01_2019-01-01_hello_hello_hello_59_100_true_false"));
        records.Add(new Record("abc_def_2020-05-02_2019-01-01_hello_hello_hello_68_100_true_false"));
        records.Add(new Record("abc_def_2020-05-03_2019-01-01_hello_hello_hello_77_100_true_false"));
        records.Add(new Record("abc_def_2020-05-04_2019-01-01_hello_hello_hello_36_100_true_false"));
        records.Add(new Record("abc_def_2020-05-05_2019-01-01_hello_hello_hello_25_100_true_false"));
        records.Add(new Record("abc_def_2021-03-01_2019-01-01_hello_hello_hello_54_100_true_false"));
        records.Add(new Record("abc_def_2021-03-02_2019-01-01_hello_hello_hello_63_100_true_false"));
        records.Add(new Record("abc_def_2021-03-03_2019-01-01_hello_hello_hello_72_100_true_false"));
        records.Add(new Record("abc_def_2021-03-04_2019-01-01_hello_hello_hello_31_100_true_false"));
        records.Add(new Record("abc_def_2021-03-05_2019-01-01_hello_hello_hello_20_100_true_false"));
        records.Add(new Record("abc_def_2021-04-01_2019-01-01_hello_hello_hello_51_100_true_false"));
        records.Add(new Record("abc_def_2021-04-02_2019-01-01_hello_hello_hello_62_100_true_false"));
        records.Add(new Record("abc_def_2021-04-03_2019-01-01_hello_hello_hello_73_100_true_false"));
        records.Add(new Record("abc_def_2021-04-04_2019-01-01_hello_hello_hello_34_100_true_false"));
        records.Add(new Record("abc_def_2021-04-05_2019-01-01_hello_hello_hello_25_100_true_false"));
        records.Add(new Record("abc_def_2021-05-01_2019-01-01_hello_hello_hello_56_100_true_false"));
        records.Add(new Record("abc_def_2021-05-02_2019-01-01_hello_hello_hello_67_100_true_false"));
        records.Add(new Record("abc_def_2021-05-03_2019-01-01_hello_hello_hello_78_100_true_false"));
        records.Add(new Record("abc_def_2021-05-04_2019-01-01_hello_hello_hello_39_100_true_false"));
        records.Add(new Record("abc_def_2021-05-05_2019-01-01_hello_hello_hello_20_100_true_false"));
        
        // this will create a list of anonymous type. If it makes more sense, you could create a class to model
        // the tabular data as well
        var shapedData = records.GroupBy(x => new {x.RecordYear, x.RecordMonth})
            .Select(x => new {
                Year = x.Key.RecordYear,
                Month = x.Key.RecordMonth,
                Total = x.Sum(i=>i.TheCount)
            })
            .ToList();
        
        foreach(var item in shapedData){
            Console.WriteLine($"Year: {item.Year} Month: {item.Month} Total: {item.Total}");
        }
    }
}

public class Record
{
    public DateTime RecordDate {get;set;}
    public int RecordMonth {get;set;}
    public int RecordYear {get;set;}
    public int TheCount {get;set;}

  public Record(string lineIn)
  {
      var splitValues = lineIn.Split('_');
      int outNum;
      TheCount = int.TryParse(splitValues[7], out outNum)?outNum:0;
      var inDateString = splitValues[2];
      DateTime outDate;
      RecordDate = DateTime.TryParseExact(inDateString, "yyyy-MM-dd", CultureInfo.InvariantCulture, DateTimeStyles.None, out outDate)? outDate : DateTime.MinValue;
      RecordMonth = RecordDate.Month;
      RecordYear = RecordDate.Year;
  }
}

提供以下输出:

Year: 2020 Month: 3 Total: 245
Year: 2020 Month: 4 Total: 260
Year: 2020 Month: 5 Total: 265
Year: 2021 Month: 3 Total: 240
Year: 2021 Month: 4 Total: 245
Year: 2021 Month: 5 Total: 260

解决方法在主post的评论区,因为作者没有把它作为答案。 这里: