使用字典按月和年填充 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);
}
}
}
结果:
帮忙?
你的Record
class长什么样?
我认为最简单的方法是修改 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的评论区,因为作者没有把它作为答案。
这里:
我需要一些帮助。
我有一个 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);
}
}
}
结果:
帮忙?
你的Record
class长什么样?
我认为最简单的方法是修改 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的评论区,因为作者没有把它作为答案。
这里: