Click here to Skip to main content
15,885,216 members
Please Sign up or sign in to vote.
3.00/5 (2 votes)
See more:
Hi,

Good day to all!
I used the Dictionary to get the keys and values, but
I got an error which I don't why always appearing:
"THE GIVEN KEY WAS NOT PRESENT IN THE DICTIONARY"

but in my input text file, that key is present.
Here's my sample input file:

MAIN_AREA CLUSTER EXC_TO_COM_DAYS
=========== =========== ================
CL1 BATAAN 1
CL1 BULACAN1A 1
NL ABRA 2
GMA1 BULACAN4 3
NL ILOCOS SUR 4
GMA2 MANILA1 7
CL1 BATAAN 1
GMA1 BULACAN4 9
CL1 BULACAN1A 2

Here's my complete code...

C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using System.IO;
namespace Clustering_Test
{
    class Program
    {
        static int T24, T3, T4;
        static void Main(string[] args)
        {
            IDictionary<string, IDictionary<string, IDictionary<string, int>>> Region = new Dictionary<string, IDictionary<string, IDictionary<string, int>>>();
            // Reading input text file
            string dirFile = @"C:\FileDir\SAMPLE_INPUT2.txt";
            string recLine;
            int recCounter = 0;
            StreamReader srTable = new StreamReader(dirFile);
            while ((recLine = srTable.ReadLine()) != null)
            {
                recCounter++;
                if (recCounter < 3) continue;
                ParseLine(recLine, Region);
            }
            Dump(Region);
            Console.ReadKey();
        }
        private static void ParseLine(string recLine, IDictionary<string, IDictionary<string, IDictionary<string, int>>> Region)
        {
            if (recLine.Trim() == String.Empty)
                return;
            try
            {
                string main_area = recLine.Substring(0, 11).Trim();
                string cluster = recLine.Substring(12, 11).Trim();
                string excDays = recLine.Substring(24, 16).Trim();

                // adding cluster type key
                if (!Region.ContainsKey(main_area))
                    Region[main_area] = new Dictionary<string, IDictionary<string, int>>();
                // adding cluster name key
                if (!Region[main_area].ContainsKey(cluster))
                {
                    Region[main_area][cluster] = new Dictionary<string, int>();
                    Region[main_area][cluster][excDays] = 0;
                }

                // summing up total
                if (Region[main_area].ContainsKey(cluster))
                 Region[main_area][cluster][excDays] += 1;
                int excDays2 = Convert.ToInt32(excDays);
                if (excDays2 < 2)
                    T24++;
                else if (excDays2 > 1 && excDays2 < 4)
                    T3++;
                else if (excDays2 > 3)
                    T4++;

            }
            catch (Exception e)
            {
                Console.Error.WriteLine("Failed to parse line \"{0}\", {1}", recLine, e.Message);
            }
        }
        private static void Dump(IDictionary<string, IDictionary<string, IDictionary<string, int>>> main_area)
        {
            foreach (string MainArea in main_area.Keys)
            {
                foreach (string Cluster in main_area[MainArea].Keys)
                {
                    foreach (string ExcDays in main_area[MainArea][Cluster].Keys)
                    {
                        Console.WriteLine("There are {0} {1} {2} named {3}", main_area[MainArea][Cluster][ExcDays], ExcDays, Cluster, MainArea);
                    }
                }
            }
            Console.WriteLine();
            Console.WriteLine("Total 24hrs:   {0} ", T24);
            Console.WriteLine("Total 3days:   {0} ", T3);
            Console.WriteLine("Total 4days:  {0} ", T4);
        }
    } // End class
} // End namespace




Please help me on this. The error comes when recLine reached
the 8 records onward.

Thank you in advance and God speed...
Posted
Updated 16-May-11 21:47pm
v2

Hello,

I just tested your code. Thanks for the full listing :)

The error is here:

C#
// adding cluster name key
if (!Region[main_area].ContainsKey(cluster))
{
    Region[main_area][cluster] = new Dictionary<string, int>();
    Region[main_area][cluster][excDays] = 0;
}


the [excDays] entry is only created in the case the cluster key does not exist, so all additional entries with the same cluster key will not have a excDays key.

use it this way, then it works:

C#
// adding cluster name key
if (!Region[main_area].ContainsKey(cluster))
{
    Region[main_area][cluster] = new Dictionary<string, int>();
}
if (!Region[main_area][cluster].ContainsKey(excDays))
{
    Region[main_area][cluster][excDays] = 0;
}


Update: check if the excDays already exists, if not => initialize with 0.

Tip for the error-searching: Don't use any try {} catch {} blocks if you're developing (especially if you get an error). If you remove the try-catch and start debugging, VisualStudio gives you the exact location of the error and you can inspect any variables at the point of error. This way, you will find the error pretty fast :)


Hope this helps.

Best regards and happy coding,
Stops
 
Share this answer
 
v2
Comments
Silver Lightning 17-May-11 4:30am    
Hi Sir Stops,
thanks responding, I tried that code but the output is not accurate,
the code:
// adding cluster name key
if (!Region[main_area].ContainsKey(cluster))
{
Region[main_area][cluster] = new Dictionary<string, int="">();
}
Region[main_area][cluster][excDays] = 0;

will reset the record in summing up the value from 1st record which is the same in the 7th record.
they have the same MAIN_AREA and CLUSTER field value, I need to sum-up the total value of all EXC_TO_COM_DAYS, as you can see if you test my old code the (cluster field)BATAAN name with (main area)CL1 has 2 value, but now it becomes 1 which is wrong.

please help me on this sir. thank you in advance
Christoph Keller 17-May-11 4:35am    
Hello,
You're welcome :)
I realized this problem exactly after I posted the answer. So I updated the answer immediately:
Use

if (!Region[main_area][cluster].ContainsKey(excDays))
{
Region[main_area][cluster][excDays] = 0;
}

then it should work.

Best regards and happy coding,
Stops
Silver Lightning 17-May-11 4:49am    
thank you for immediate response sir sTops,
the code you've given is only sum up if
the same value of EXC_TO_COM_DAYS.
eg: if I change the value of EXC_TO_COM_DAYS of "BATAAN" from 1 to 2 in the first record, the 7th record which has the same of 1st record value(BATAAN also) will not sum up. Because it has a value of 1 which is now different from 1st record which I changed to 2. The output should result to 1 record if it has the same MAIN_AREA and CLUSTER. Please help me sir. I know it's too much. But I really needed it badly.

Thank you and God bless...
Christoph Keller 17-May-11 4:56am    
If I understand you right, then the Dictionary<string, int=""> at the end is too much.

Use it this way:

static void Main(string[] args)
{
IDictionary<string, idictionary<string,="" int="">> Region = new Dictionary<string, idictionary<string,="" int="">>();
// Reading input text file
string dirFile = @"C:\temp\input.txt";
string recLine;
int recCounter = 0;
StreamReader srTable = new StreamReader(dirFile);
while ((recLine = srTable.ReadLine()) != null)
{
recCounter++;
if (recCounter < 3)
continue;
ParseLine(recLine, Region);
}
Dump(Region);
Console.ReadKey();
}
private static void ParseLine(string recLine, IDictionary<string, idictionary<string,="" int="">> Region)
{
if (recLine.Trim() == String.Empty)
return;
string main_area = recLine.Substring(0, 11).Trim();
string cluster = recLine.Substring(12, 11).Trim();
string excDays = recLine.Substring(24, 16).Trim();

// adding cluster type key
if (!Region.ContainsKey(main_area))
Region[main_area] = new Dictionary<string, int="">();
// adding cluster name key
if (!Region[main_area].ContainsKey(cluster))
{
Region[main_area][cluster] = 0;
}

// summing up total
if (Region[main_area].ContainsKey(cluster))
Region[main_area][cluster] += 1;
int excDays2 = Convert.ToInt32(excDays);
if (excDays2 < 2)
T24++;
else if (excDays2 > 1 && excDays2 < 4)
T3++;
else if (excDays2 > 3)
T4++;
}
private static void Dump(IDictionary<string, idictionary<string,="" int="">> main_area)
{
foreach (string MainArea in main_area.Keys)
{
foreach (string Cluster in main_area[MainArea].Keys)
{

Console.WriteLine("There are {0} {1} named {2}", main_area[MainArea][Cluster], Cluster, MainArea);
}
}
Console.WriteLine();
Console.WriteLine("Total 24hrs: {0} ", T24);
Console.WriteLine("Total 3days: {0} ", T3);
Console.WriteLine("Total 4days: {0} ", T4);
}


is this working?

Best regards,
Stops
Christoph Keller 17-May-11 5:06am    
It seems that the edit form removed the "int" out of all IDictionary<string, int> textes, don't forget to add them properly.

Sorry for this.
please explain to me why you use IDictionary<blabla> and not Dictionary<blabla>.
 
Share this answer
 
Comments
Silver Lightning 17-May-11 3:41am    
hi sir Thomas,
Even if I use the Dictionary, I'm getting the same error "KEY WAS NOT PRESENT IN THE DICTIONARY". Can you see what went wrong to my code sir?

thank you in advance sir. please help me

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900