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

C# 如何将字典中的所有值从一个键添加到下一个键?,c#,dictionary,C#,Dictionary,我有一个字典,它的键是DateTime.Now.Date,值是整数。我需要以某种方式将一个输入键到下一个键的所有整数相加。它还应该包括开始和结束整数的值。我怎么能这么做?此外,我如何将这本词典保存到计算机中,以便在打开程序时加载同一本词典并不断添加到其中 我的建议是将DateTime保留为自然类型,这样生活会更轻松 你可以这样做 给定的 public static void Serialize(Dictionary<DateTime, int> dictionary, Stream

我有一个字典,它的键是DateTime.Now.Date,值是整数。我需要以某种方式将一个输入键到下一个键的所有整数相加。它还应该包括开始和结束整数的值。我怎么能这么做?此外,我如何将这本词典保存到计算机中,以便在打开程序时加载同一本词典并不断添加到其中

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

你可以这样做

给定的

public static void Serialize(Dictionary<DateTime, int> 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<DateTime, int> Deserialize(Stream stream)
{
   var reader = new BinaryReader(stream);
   var count = reader.ReadInt32();
   var dictionary = new Dictionary<DateTime, int>(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<DateTime, int>();
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);

基于谓词筛选值序列

基本上,您可以使用字典上的where子句作为它的基本用法

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

此外,您可能还想了解Linq

更新

// Create some data
var dictionary = new Dictionary<DateTime, int>();
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);
有没有可能有一本键相同但不相同的词典 他们有不同的价值观

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

你可以这样做,看看这个问题

var list=新列表()
然后,在序列化方法中,只需更改

Dictionary<DateTime, int>
字典

KeyValuePair

列表
然后添加

list.Add(new KeyValuePair<DataTime, int>(myDate,ads));
添加(新的KeyValuePair(myDate,ads));
我是通过一个没有循环的BinaryFormatter学习到这一点的,对我来说似乎有点简单。只是保存和检索部分,而不是其他部分

private void SaveAsBinary()
        {
            Dictionary<DateTime, int> myData = new Dictionary<DateTime, int>();
            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<DateTime,int> myDataFromDisk = (Dictionary<DateTime,int>)bf.Deserialize(fs);

                foreach (KeyValuePair<DateTime,int> kv in myDataFromDisk)
                {
                    Debug.Print($"Key = {kv.Key}, Value = {kv.Value}");
                }
            }
        }
private void SaveAsBinary()
{
Dictionary myData=newdictionary();
myData.Add(新日期时间(2018,4,11),24);
myData.Add(新日期时间(2017,4,13),32);
myData.Add(新日期时间(2016,7,22),37);
BinaryFormatter bf=新的BinaryFormatter();
使用(Stream fs=newfilestream(“myData.dat”,FileMode.Create,FileAccess.Write,FileShare.None))
{
序列化(fs,myData);
}
Show(“保存为二进制的字典”);
}
私人无效检索
{
BinaryFormatter bf=新的BinaryFormatter();
使用(Stream fs=File.OpenRead(“myData.dat”))
{
字典myDataFromDisk=(字典)bf.反序列化(fs);
foreach(myDataFromDisk中的KeyValuePair kv)
{
Print($“Key={kv.Key},Value={kv.Value}”);
}
}
}
我需要以某种方式将一个输入键到下一个键的所有整数相加

我可以感觉到您在
Linq
代码中对此没有什么混淆,所以这里是更简单的代码

假设您的词典是
dictionary dateNumDict

您可以创建一个如下所示的方法

    int GetSumOfIntBetweenTwoDateString(Dictionary<string, int> dateNumDict, string startKey, string endKey)
    {
        int sum = 0;
        if (dateNumDict.ContainsKey(startKey) && dateNumDict.ContainsKey(endKey))
        {
            List<string> 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;
    }
    Dictionary<string, int> LoadDict()
    {
        Dictionary<string, int> dateNumDict = new Dictionary<string, int>();
        if(File.Exists("Data.dat"))
        {
            try
            {
                BinaryFormatter binaryFormatter = new BinaryFormatter();
                using (FileStream fileStream = new FileStream("Data.dat", FileMode.Open))
                {
                    dateNumDict = (Dictionary<string, int>)binaryFormatter.Deserialize(fileStream) ;
                }
            }
            catch (Exception ex) { /*log exception if you want*/ }
        }
        return dateNumDict;
    }
正如传递字典一样,您不必担心从该方法获取更新的(输出)字典

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

例如

字典的值如下

        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);
如果您将“2018年5月27日12:19:11 PM”到“2018年5月27日12:25:11 PM”之间的数据添加到“2018年5月27日12:25:11 PM”中,则会将所有三个值相加,按照顺序,这些日期之间有三个条目


此外,我如何将这本词典保存到计算机中,以便在打开程序时加载同一本词典

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

您可以使用如下方法

    void SaveDict(Dictionary<string, int> 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*/ }
    }
另一种读取数据的方法如下所示

    int GetSumOfIntBetweenTwoDateString(Dictionary<string, int> dateNumDict, string startKey, string endKey)
    {
        int sum = 0;
        if (dateNumDict.ContainsKey(startKey) && dateNumDict.ContainsKey(endKey))
        {
            List<string> 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;
    }
    Dictionary<string, int> LoadDict()
    {
        Dictionary<string, int> dateNumDict = new Dictionary<string, int>();
        if(File.Exists("Data.dat"))
        {
            try
            {
                BinaryFormatter binaryFormatter = new BinaryFormatter();
                using (FileStream fileStream = new FileStream("Data.dat", FileMode.Open))
                {
                    dateNumDict = (Dictionary<string, int>)binaryFormatter.Deserialize(fileStream) ;
                }
            }
            catch (Exception ex) { /*log exception if you want*/ }
        }
        return dateNumDict;
    }

它还应该包括开始和结束整数的值
请解释这一行,您没有提到任何关于开始和结束整数的内容。假设我需要将2018年5月26日到2018年6月23日的数字相加。它应该在计算中包含这些日期的值。是否有任何理由将日期存储为字符串?不,我是编程新手,不确定这样做的最佳方式。我只是觉得输入一个字符串比输入一个日期时间更容易。你能写一些关于字典的更多信息吗。我不明白这一切意味着什么。更新您知道我将如何在方法中输入DateTime.Now.Date吗?当我试图以2018年5月26日的形式输入时,它说它无法将int转换为System.DateTime。@DanielV
public void MyMethod(DateTime myDate){..}
usage
MyMethod(DateTime.Now.Date)
你能用这种方法吗(2018年5月26日)
    void SaveDict(Dictionary<string, int> 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(dateNumDict);
    Dictionary<string, int> LoadDict()
    {
        Dictionary<string, int> dateNumDict = new Dictionary<string, int>();
        if(File.Exists("Data.dat"))
        {
            try
            {
                BinaryFormatter binaryFormatter = new BinaryFormatter();
                using (FileStream fileStream = new FileStream("Data.dat", FileMode.Open))
                {
                    dateNumDict = (Dictionary<string, int>)binaryFormatter.Deserialize(fileStream) ;
                }
            }
            catch (Exception ex) { /*log exception if you want*/ }
        }
        return dateNumDict;
    }
dateNumDict = LoadDict();