I'm an experienced PHP developer transitioning to C#. At present I am working on a Windows Forms application.
I found in my searches that C# doesn't support associative arrays in the same loose fashion PHP does. I have found info on Dictionary and something about "structs" which seem to be class objects.
The trouble I am having is getting my head around not only an Associative array, but a multi dimensional one that I want to use for keeping multiple counts in a series of loops.
The application is reading a text log file, searching for a predefined string, pulling out the date on that line when the string is found, and incrementing a count for that string match on that date.
In PHP, it would be as easy as this:
// Initialize
$count_array[$string_date][$string_keyword] = 0;
...
// if string is found
$count_array[$string_date][$string_keyword] += 1;
...
// To ouput contents of array
foreach($count_array as $date -> $keyword_count_array) {
echo $date; // output date
foreach($keyword_count_array as $keyword -> $count) {
echo $keyword . ": " . $count;
}
}
It seems to be a little more involved in C# (which isn't a bad thing). I have tried using an suggestion I found on another similar question but I don't really follow how to either increment or iterate/output the contents:
// Initialize
var count_array = new Dictionary<string, Dictionary<string, int>>();
count_array = null;
...
// if string is found - I think the second reference is supposed to be a Dictionary object??
count_array[string_date.ToShortDateString()][string_keyword]++;
...
// To ouput contents of "array"
foreach (KeyValuePair<string, Dictionary<string, int>> kvp in exportArray)
{
foreach(KeyValuePair<string, int> kvp2 in kvp.Value)
{
MessageBox.Show(kvp.Key + " - " + kvp2.Key + " = " + kvp2.Value);
}
}
Am I even on the right track? Or does someone have a better/cleaner method of mimicing the PHP code above?
UPDATE
With the above C# code, I actually get an error at the "// if string is found " line. The error is "Object reference is not set to an instance of an object". I am assuming that it is because I have a string in the secound reference, not a Dictionary object. So right now, I am unsure how to increment.
UPDATE 2
Thanks everyone for your time. Current code is now functional thanks to understanding how Dictionary's work. However all advice regarding the use of classes and objects for this situation is not lost either. I may refactor to suit.
The code itself looks sound, the only thing I see missing is there are no checks to see if the values exist before incrementing them.
Before you call
count_array[string_date.ToShortDateString()][string_keyword]++;
You'll need to do:
string shortDate = string_date.ToShortDateString();
if (!count_array.ContainsKey(shortDate))
{
count_array.Add(shortDate, new Dictionary<string, int>());
}
if (!count_array[shortDate].ContainsKey(string_keyword))
{
count_array[shortDate].Add(string_keyword, 0);
}
Before you try incrementing anything.
You need to initialize your dictionary entries by calling .Add or ["key"] = value. Calling ++ on an uninitialized dictionary entry won't work. Depending on what exactly it is you're trying to accomplish though it might be a good idea to use a class.
You can use a tuple to create a multi-dimensional key for use in a Dictionary.
Dictionary<Tuple<TKey1,TKey2>,TValue>
Or a Dictionary of Dictionary:
Dictionary<TKey1,Dictionart<TKey2,Tvalue>>
The second one is more annoying to work with, but has the upside that you can index into it with just the first key and then get all key-value pairs associated with that key.
But perhaps you can use some linq, but your code is a bit incomplete for that.
What about creating a class for this?
public class LogEntry
{
private List<int> _lines = new List<int>();
public string LogContent { get;set; }
public DateTime Time { get;set; }
public List<int> Lines { get { return _lines; } }
}
You'd still have a dictionary of probably DateTime, LogEntry? Not entirely sure what exactly you need / what the key is.
Anyways, creating a class seems to be the "correct" way as you can express your intend more clearly.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With