如何将字典中的所有值从一个键添加到下一个键?

我有一个字典,其中DateTime.Now.Date转换为字符串作为键,一个整数作为值。 我需要以某种方式将所有整数从一个输入的密钥加到下一个密钥。 它还应包括开始和结束整数的值。 我怎么能这样做? 另外,我怎么能将这个词典保存到计算机中,以便在我打开程序时加载相同的字典并继续添加到它?

我的建议是将DateTime保留为自然类型,让生活更轻松

你可以这样做

特定

 public static void Serialize(Dictionary dictionary, Stream stream) { var writer = new BinaryWriter(stream); writer.Write(dictionary.Count); foreach (var kvp in dictionary) { writer.Write(kvp.Key.ToBinary()); writer.Write(kvp.Value); } writer.Flush(); } public static Dictionary Deserialize(Stream stream) { var reader = new BinaryReader(stream); var count = reader.ReadInt32(); var dictionary = new Dictionary(count); for (var n = 0; n < count; n++) { var key = DateTime.FromBinary(reader.ReadInt64()); var value = reader.ReadInt32(); dictionary.Add(key, value); } return dictionary; } 

用法

 // Create some data var dictionary = new Dictionary(); dictionary.Add(DateTime.Now.AddDays(-10), 34); dictionary.Add(DateTime.Now.AddDays(-5), 234); dictionary.Add(DateTime.Now.AddDays(-2), 345); dictionary.Add(DateTime.Now, 434); // Example using sum var sum = dictionary.Where(x => x.Key > DateTime.Now.AddDays(-6) && x.Key < DateTime.Now.AddDays(-1)) .Sum(x => x.Value); Console.WriteLine(sum); // write to file using (var fileStrem = new FileStream(@"D:\dict.dat", FileMode.Create)) { Serialize(dictionary, fileStrem); } // Read from file using (var fileStrem = new FileStream(@"D:\dict.dat", FileMode.Open)) { dictionary = Deserialize(fileStrem); } // sanity check sum = dictionary.Where(x => x.Key > DateTime.Now.AddDays(-6) && x.Key < DateTime.Now.AddDays(-1)) .Sum(x => x.Value); Console.WriteLine(sum); 

产量

 579 579 

更新

Enumerable.Where方法(IEnumerable,Func)

根据谓词过滤一系列值。

基本上你可以在字典上使用where子句,因为它基本上只是KeyValuePair结构

定义可以设置或检索的键/值对。

您也可以阅读有关Linq的内容

语言集成查询(LINQ)

更新

是否可以使用具有相同但具有不同值的键的字典?

在这种情况下,最好只使用List

你可以这样做,看看这个问题键值对列表

 var list = new List>() 

然后在你的序列化方法中只需更改所有的事件

 Dictionary 

 KeyValuePair 

 List> 

然后添加

 list.Add(new KeyValuePair(myDate,ads)); 

我用BinaryFormatter Done学习了这个,没有循环,对我来说似乎有点简单。 只是保存和检索部分而不是其余部分。

 private void SaveAsBinary() { Dictionary myData = new Dictionary(); myData.Add(new DateTime(2018,4,11), 24); myData.Add(new DateTime(2017,4,13), 32); myData.Add(new DateTime(2016,7,22), 37); BinaryFormatter bf = new BinaryFormatter(); using (Stream fs = new FileStream("myData.dat", FileMode.Create, FileAccess.Write, FileShare.None)) { bf.Serialize(fs, myData); } MessageBox.Show("Saved Dictionary as binary"); } private void RetrieveDictionay() { BinaryFormatter bf = new BinaryFormatter(); using (Stream fs = File.OpenRead("myData.dat")) { Dictionary myDataFromDisk = (Dictionary)bf.Deserialize(fs); foreach (KeyValuePair kv in myDataFromDisk) { Debug.Print($"Key = {kv.Key}, Value = {kv.Value}"); } } } 

我需要以某种方式将所有整数从一个输入的密钥加到下一个密钥。

我可以感觉到你为此目的在Linq代码中几乎没有混淆,所以这里的代码更简单。

假设您的字典是Dictionary dateNumDict

你可以创建一个像下面这样的方法

  int GetSumOfIntBetweenTwoDateString(Dictionary dateNumDict, string startKey, string endKey) { int sum = 0; if (dateNumDict.ContainsKey(startKey) && dateNumDict.ContainsKey(endKey)) { List keys = dateNumDict.Keys.ToList(); int startIndex = keys.IndexOf(startKey); int endIndex = keys.IndexOf(endKey); for(int i = startIndex; i <= endIndex; i++) { sum += dateNumDict[keys[i]]; } } return sum; } 

此方法将接受您的字典,启动键和结束键作为输入,并将所有整数从开始键的值加到结束键的值,并返回结果总和。

这还将检查字典中是否存在源键或目标键,并相应地执行任务。

调用这种方法将是,

 int sum = GetSumOfIntBetweenTwoDateString(dateNumDict, sourceDateKey, destDateKey); 

当传递字典通过引用传递时 ,您不必担心从此方法获取更新(输出)字典。

注意如果您的要求就像添加关键日期时间介于开始时间和结束时间之间的所有数据,则必须注意字典中数据的顺序。

对于Ex。

字典有价值

  dateNumDict.Add("5/27/2018 12:19:11 PM", 1); dateNumDict.Add("5/27/2018 12:29:11 PM", 2); dateNumDict.Add("5/27/2018 12:25:11 PM", 3); 

如果你在“5/27/2018 12:19:11 PM”到“5/27/2018 12:25:11 PM”之间添加数据,它会将所有三个值相加,按顺序,它们之间有三个条目这些日期。


另外,我怎么能将这个字典保存到计算机中,这样当我打开程序时会加载相同的字典

为此你可以使用序列化的概念(有多种方法来序列化数据,但在这里我们将使用二进制序列化)

你可以有如下方法,

  void SaveDict(Dictionary dateNumerDict) { try { BinaryFormatter binaryFormatter = new BinaryFormatter(); using (Stream dataStream = new FileStream("Data.dat", FileMode.Create)) { binaryFormatter.Serialize(dataStream, dateNumerDict); } } catch (Exception ex) { /*log exception if you want*/ } } 

SaveDict方法将接受您的字典作为输入并将其保存到名为“Data.dat”的文件中。

请注意,您需要using System.Runtime.Serialization.Formatters.Binary;进行添加using System.Runtime.Serialization.Formatters.Binary; 使用BinaryFormatterusing System.IO;File顶部使用FileStream相关的类。

调用这种方法很简单,

 SaveDict(dateNumDict); 

另一种方法,读取数据将如下所示

  Dictionary LoadDict() { Dictionary dateNumDict = new Dictionary(); if(File.Exists("Data.dat")) { try { BinaryFormatter binaryFormatter = new BinaryFormatter(); using (FileStream fileStream = new FileStream("Data.dat", FileMode.Open)) { dateNumDict = (Dictionary)binaryFormatter.Deserialize(fileStream) ; } } catch (Exception ex) { /*log exception if you want*/ } } return dateNumDict; } 

此方法将查找文件“Data.dat”。 如果它确实存在,它将反序列化它并从中读取Dictionary并返回该字典。

调用这种方法,

 dateNumDict = LoadDict();