AT-2017
AT-2017

Reputation: 3149

Implement List of Objects Using Dictionary Key/Value Pair

I am trying to work with Dictionary<> along with List<> for searching purpose. I know, I can do this easily with List<> as follows:

var con = (from c in db.Customers
           where c.Status == status
           select c).ToList(); 

But preferred and tried to implement the above with Dictionary<>. My concept (We all know that) is using the key/value will increase the search option performance. This looks simple and stuck a bit. Here what I've tried:

static void Main(string[] args)
{
   Dictionary<string, Customer> custDictionary = new Dictionary<string, Customer>(); //Dictionary declared

   List<Customer> lst = new List<Customer>(); //List of objects declared

   Customer aCustomer = new Customer(); //Customer object created

   /**Assign values - Starts**/
   aCustomer.CustomerId = 1001;
   aCustomer.CustomerName = "John";
   aCustomer.Address = "On Earth";
   aCustomer.Status = "Active";

   aCustomer.CustomerId = 1002;
   aCustomer.CustomerName = "James";
   aCustomer.Address = "On Earth";
   aCustomer.Status = "Inactive";
   /**Assign values - Ends**/

   custDictionary.Add(aCustomer.Status, aCustomer); //Added to the dictionary with key and value

   string status = Console.ReadLine().ToUpper();

   if (custDictionary.ContainsKey(status)) //If key found in the dictionary
   {
      Customer cust = custDictionary[status];
      Console.WriteLine(cust.CustomerId + " " + cust.CustomerName); //Outputs the final result - Right now no result found here
   }

  Console.ReadKey();
}

public class Customer
{
   public int CustomerId { get; set; }
   public string CustomerName { get; set; }
   public string Address { get; set; }
   public string Status { get; set; }
}  

Unfortunately, the above doesn't return any result. What I am trying is to get customer details by passing status key and again passed Customer object as the value. I am not sure what I am missing here.

One more thing, in real-life projects, we get database results as list. So in this scenario, if Dictionary<> is used, I believe, the database results should be kept as follows:

lst.Add(aCustomer); //As database will have more result or data simply

On the other hand, I believe, the dictionary should look like the below:

Dictionary<string, List<Customer>> custDictionary = new Dictionary<string, List<Customer>>();

My question - Is it a good idea to pass a list of objects in the dictionary for the key/vale pair and I've tried using so. But didn't get the output yet.

Note: This sounds like a novice question and yes, it's. I've tried to search online and still studying it. I apology to ask such a question and would expect some answers if there are any better ways to do the above.

Upvotes: 0

Views: 3285

Answers (5)

Ofir Winegarten
Ofir Winegarten

Reputation: 9355

If you already has the list and want to create a Dictionary<string, List<Customer>> you can do it with this:

Dictionary<string, List<Customer>> dict = 
        list.GroupBy(c=>c.Status.ToUpper()).ToDictionary(g => g.Key, g=> g.ToList());

And iterate it:

foreach (var customer in dict[status.ToUpper()])
{
}

But,

I don't see the value in doing so. if you need to get all the customers with a specific status stay with what you have - a simple linq query.

Upvotes: 1

Clive Ciappara
Clive Ciappara

Reputation: 558

UPDATED

If you want to store them in a list, you can do the following code. To select the items, you can then use Linq, and in this way you don't have the issue of duplicate values in a dictionary:

        var lst = new List<Customer>(); //List of objects declared

        lst.AddRange(
            new List<Customer>() {
                new Customer()
                {
                    CustomerId = 1001,
                    CustomerName = "John",
                    Address = "On Earth",
                    Status = "Active"
                },
                new Customer()
                {
                    CustomerId = 1002,
                    CustomerName = "James",
                    Address = "On Earth",
                    Status = "Inactive"
                }
            }
        );

        var status = Console.ReadLine();
        var selected = lst.Where(x => x.Status.ToUpper() == status.ToUpper()).ToList();
        foreach (var item in selected)
        {
            Console.WriteLine(item.CustomerId + " " + item.CustomerName);
        }

UPDATE 2

If you want to add the above list in a dictionary, you can do as follows:

var custDictionary = new Dictionary<string, List<Customer>>();

// the above code for the list

custDictionary.Add("keyname", lst);

ORIGINAL ANSWER

You are saving one customer only since you are overwriting the first customer with the second one:

Dictionary<string, Customer> custDictionary = new Dictionary<string, Customer>();
List<Customer> lst = new List<Customer>();

// Add first customer
var aCustomer = new Customer()
{
    CustomerId = 1001,
    CustomerName = "John",
    Address = "On Earth",
    Status = "Active"
};
custDictionary.Add(aCustomer.Status.ToUpper(), aCustomer);

// Add second customer
var bCustomer = new Customer()
{
    CustomerId = 1002,
    CustomerName = "James",
    Address = "On Earth",
    Status = "Inactive"
};
custDictionary.Add(bCustomer.Status.ToUpper(), bCustomer);

Also you need to store the Status as uppercase, since you are checking if the status exist in uppercase:

string status = Console.ReadLine().ToUpper();
if (custDictionary.ContainsKey(status)) //If key found in the dictionary
{
    Customer cust = custDictionary[status];
    Console.WriteLine(cust.CustomerId + " " + cust.CustomerName); //Outputs the final result - Right now no result found here
}

Console.ReadKey();

Upvotes: 2

user8537597
user8537597

Reputation:

Your are not getting any output because your are converting your input to uppercase while you have insert the keys in pascalcase and in case of C# collections keys are case sensitive. in this way your input does not matched to any key in collection

change your line number : 29 to this code

 string status = Console.ReadLine();

and insert "Inactive" from you console this key exist in your collection so you will desired result..

Upvotes: 1

Ravi Kanth
Ravi Kanth

Reputation: 1210

First of all your dictionary key should be customerId not status. it will be a good practice to check if dictionary contains the key other wise it will throw the exception already same key is added. so its better to check then perform add or update in the dictionary.

static void Main(string[] args)
{
   Dictionary<string, Customer> custDictionary = new Dictionary<string, Customer>(); //Dictionary declared

   List<Customer> lst = new List<Customer>(); //List of objects declared

   Customer aCustomer = new Customer(); //Customer object created

   /**Assign values - Starts**/
   aCustomer.CustomerId = 1001;
   aCustomer.CustomerName = "John";
   aCustomer.Address = "On Earth";
   aCustomer.Status = "Active";
   if (!custDictionary.ContainsKey(aCustomer.CustomerId))
        custDictionary.Add(aCustomer.CustomerId, aCustomer);
    else
        custDictionary[aCustomer.CustomerId] = aCustomer;

   aCustomer.CustomerId = 1002;
   aCustomer.CustomerName = "James";
   aCustomer.Address = "On Earth";
   aCustomer.Status = "Inactive";
   /**Assign values - Ends**/

   if (!custDictionary.ContainsKey(aCustomer.CustomerId))
        custDictionary.Add(aCustomer.CustomerId, aCustomer);
    else
        custDictionary[aCustomer.CustomerId] = aCustomer;


   string status = Console.ReadLine().ToUpper();

   if (custDictionary.ContainsKey(aCustomer.CustomerId)) //If key found in the dictionary
   {
      Customer cust = custDictionary[aCustomer.CustomerId];
      Console.WriteLine(cust.CustomerId + " " + cust.CustomerName); //Outputs the final result - Right now no result found here
   }

  Console.ReadKey();
}

Upvotes: 1

Amit Kumar Singh
Amit Kumar Singh

Reputation: 4475

Even if you are adding status as key, there are 2 problems with your code.

  1. You need to create 2 objects to create 2 customers, one by one. You are adding customer only once, and assigning values twice.

  2. Console.ReadLine().ToUpper() - Remove the ToUpper() since you are adding values in mixed case. If you want to do that, initialize dictionary with StringComparer.InvariantCultureIgnoreCase.

This will work for you.

Dictionary<string, Customer> custDictionary = new Dictionary<string, Customer>(StringComparer.InvariantCultureIgnoreCase); //Dictionary declared

   List<Customer> lst = new List<Customer>(); //List of objects declared

   Customer aCustomer = new Customer(); //Customer object created

   /**Assign values - Starts**/
   aCustomer.CustomerId = 1001;
   aCustomer.CustomerName = "John";
   aCustomer.Address = "On Earth";
   aCustomer.Status = "Active";
   custDictionary.Add(aCustomer.Status, aCustomer); //Added to the dictionary with key and value

   Customer bCustomer = new Customer(); //Customer object created
   bCustomer.CustomerId = 1002;
   bCustomer.CustomerName = "James";
   bCustomer.Address = "On Earth";
   bCustomer.Status = "Inactive";


   custDictionary.Add(bCustomer.Status, bCustomer); //Added to the dictionary with key and value

   string status = Console.ReadLine().ToUpper();

   if (custDictionary.ContainsKey(status)) //If key found in the dictionary
   {
      Customer cust = custDictionary[status];
      Console.WriteLine(cust.CustomerId + " " + cust.CustomerName); //Outputs the final result - Right now no result found here
   }

  Console.ReadLine();

Upvotes: 1

Related Questions