I have a dictionary that has a DateTime.Now.Date converted to string as the key and an integer as the value. I need to somehow add up all the integers from one inputted key to the next key. It should also include the values for the start and ending integers. How could I do that? In addition how could I save this dictionary into the computer so that when I open up the program is loads up the same dictionary and keeps on adding to it?
-
1`It should also include the values for the start and ending integers` please explain this line, you didn't mention anything about start and end integers. – TheGeneral May 27 '18 at 01:16
-
Let say I need to add up something from 5/26/2018 to 6/23/2018. It should include the values from those dates as well in the calculation. – Daniel V. May 27 '18 at 01:19
-
Is there any reason you are storing the dates as strings? – TheGeneral May 27 '18 at 01:20
-
No I am new to programming and not sure the best way to do this. I just thought that it would be easier to input a string then a Datetime. – Daniel V. May 27 '18 at 01:21
3 Answers
My advice is leave the DateTime
in its natural type, it makes life easier
You could do something like this
Given
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;
}
Usage
// 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);
Output
579
579
Update
Enumerable.Where Method (IEnumerable, Func)
Filters a sequence of values based on a predicate.
Essentially you can use the where clause on a dictionary as its basically just KeyValuePair Structure
Defines a key/value pair that can be set or retrieved.
Also you might want to read about Linq
Language Integrated Query (LINQ)
Update
Is it possible to have a dictionary with keys that are the same but they have different values?
You are better of just to use a List<T>
in this case
You could do this, check out this question Key Value Pair List
var list = new List<KeyValuePair<DateTime, int>>()
Then in your serialisation methods just change all occournces of
Dictionary<DateTime, int>
to
KeyValuePair<DateTime, int>
and
List<KeyValuePair<DateTime, int>>
Then to add
list.Add(new KeyValuePair<DataTime, int>(myDate,ads));

- 79,002
- 9
- 103
- 141
-
Could you please write some more information about dictionary.Where. I don't understand what it all means. – Daniel V. May 27 '18 at 01:57
-
-
Do you know how I would input an a DateTime.Now.Date into a method? When I try to input it as a 5/26/2018 it says it cannot convert int to System.DateTime. – Daniel V. May 27 '18 at 02:09
-
@DanielV. `public void MyMethod(DateTime myDate) {..}` usage `MyMethod(DateTime.Now.Date)` – TheGeneral May 27 '18 at 02:11
-
-
-
-
@DanielV. to convert a string into a `DateTime` you can do this `DateTime date = DateTime.Parse("5/26/2018");` – TheGeneral May 27 '18 at 02:16
-
-
-
Are you sure can serialize DateTime type? I am having trouble doing it. – Daniel V. May 27 '18 at 04:49
-
I learned this with a BinaryFormatter Done without the loops and seems a bit simpler to me. Just the saving and retrieving parts not the rest.
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}");
}
}
}

- 14,926
- 3
- 18
- 27
I need to somehow add up all the integers from one inputted key to the next key.
I could sense you had little confusion in Linq
code for this purpose, so here is simpler code.
Suppose your dictionary is Dictionary<string, int> dateNumDict
you can create a method like below
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;
}
This method will accept your dictionary, start Key and end key as input and sum all integers from start key's value to end key's value, and return the resultant sum.
This will also check if source or destination keys are there in dictionary or not and perform task accordingly.
calling of this method will be,
int sum = GetSumOfIntBetweenTwoDateString(dateNumDict, sourceDateKey, destDateKey);
as passing dictionary is passing by reference, you will not need to worry for taking an updated (output) dictionary from this method.
Note That if your requirement is like adding all data which's key date's time is between start time and end time, you must mind the order of the data in your dictionary.
For Ex.
dictionary have values like
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);
and if you add data between "5/27/2018 12:19:11 PM" to "5/27/2018 12:25:11 PM", it will sum all three values, as in sequence, there are three entries between these dates.
In addition how could I save this dictionary into the computer so that when I open up the program is loads up the same dictionary
for that you can use concept of serialization (there are multiple ways to serialize data, but here we will use binary serialization)
you can have methods like below,
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*/ }
}
this SaveDict
method will accept your dictionary as an input and save it to a file named "Data.dat".
Note that you will need to add using System.Runtime.Serialization.Formatters.Binary;
to use BinaryFormatter
and using System.IO;
to use File
and Stream
related classes at the top of your file.
calling of this method is simply,
SaveDict(dateNumDict);
another method, to read data will be like below
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;
}
this method will look for a file "Data.dat". if it does exist, it will deserialize it and read Dictionary<string, int>
out of it and return that dictionary.
calling of this method,
dateNumDict = LoadDict();

- 1,821
- 1
- 17
- 30